https://fedorahosted.org/freeipa/ticket/2041

I'm not sure if update_info and other new classes should be in details.js.
--
Petr Vobornik
From 0506538ec9da347f2d2b7bac103b9c06fc405c2f Mon Sep 17 00:00:00 2001
From: Petr Vobornik <pvobo...@redhat.com>
Date: Wed, 2 Nov 2011 16:43:00 +0100
Subject: [PATCH] Extending facet's mechanism of gathering changes

https://fedorahosted.org/freeipa/ticket/2041

Adding option to gathering changes for update from widgets, sections, details facet.

Changes are represented by update_info { fields [] ((field_info)), commands [] ((command_info))  } object.

* On calling get_update_info() method widget, section and facet returns update_info object which represents all changes in nested objects. Thus usually widgets are creating update_infos, their containers are merging them.
* This object can be then used in details facet update method. In order to use it command_mode = 'init' has to be set. Command mode was introduced to support backward compatibility.
* command_info consists of command and priority. Priority can be set to specify exact exectuting order of commands. It can be defined on facet level by setting widget's priority. When widgit is creating command_info it should pas its priority to it.
---
 install/ui/details.js |  347 ++++++++++++++++++++++++++++++++++++++++--------
 install/ui/ipa.js     |   10 +-
 install/ui/widget.js  |   15 ++-
 3 files changed, 310 insertions(+), 62 deletions(-)

diff --git a/install/ui/details.js b/install/ui/details.js
index 15056204f72ef2095862c2c35d24cd47fbc819b3..621d47ecdd95672d530b78c0eb707e4af96002d8 100644
--- a/install/ui/details.js
+++ b/install/ui/details.js
@@ -207,6 +207,20 @@ IPA.details_section = function(spec) {
         }
     };
 
+    that.get_update_info = function() {
+
+        var update_info = IPA.update_info_builder.new_update_info();
+
+        var fields = that.fields.values;
+        for(var i=0; i < fields.length; i++) {
+            update_info = IPA.update_info_builder.merge(
+                update_info,
+                fields[i].get_update_info());
+        }
+
+        return update_info;
+    };
+
     init();
 
     // methods that should be invoked by subclasses
@@ -280,6 +294,8 @@ IPA.details_facet = function(spec) {
     that.entity = spec.entity;
     that.pre_execute_hook = spec.pre_execute_hook;
     that.post_update_hook = spec.post_update_hook;
+    that.update_command_name = spec.update_command_name || 'mod';
+    that.command_mode = spec.command_mode || 'save'; // [save, info]
 
     that.label = spec.label || IPA.messages && IPA.messages.facets && IPA.messages.facets.details;
     that.facet_group = spec.facet_group || 'settings';
@@ -398,11 +414,7 @@ IPA.details_facet = function(spec) {
                 if (that.update_button.hasClass('action-button-disabled')) return false;
 
                 if (!that.validate()) {
-                    var dialog = IPA.message_dialog({
-                        title: IPA.messages.dialogs.validation_title,
-                        message: IPA.messages.dialogs.validation_message
-                    });
-                    dialog.open();
+                    that.show_validation_error();
                     return false;
                 }
 
@@ -598,6 +610,7 @@ IPA.details_facet = function(spec) {
         that.enable_update(false);
     };
 
+
     that.validate = function() {
         var valid = true;
         var sections = that.sections.values;
@@ -608,46 +621,40 @@ IPA.details_facet = function(spec) {
         return valid;
     };
 
-    that.update = function(on_win, on_fail) {
 
-        function on_success(data, text_status, xhr) {
-            if (on_win)
-                on_win(data, text_status, xhr);
-            if (data.error)
-                return;
+    that.on_update_success = function(data, text_status, xhr) {
 
-            if (that.post_update_hook) {
-                that.post_update_hook(data, text_status);
-                return;
-            }
+        if (data.error)
+            return;
 
-            var result = data.result.result;
-            that.load(result);
+        if (that.post_update_hook) {
+            that.post_update_hook(data, text_status);
+            return;
         }
 
-        function on_error(xhr, text_status, error_thrown) {
-            if (on_fail)
-                on_fail(xhr, text_status, error_thrown);
-        }
+        var result = data.result.result;
+        that.load(result);
+    };
+
+    that.on_update_error = function(xhr, text_status, error_thrown) {
+    };
 
-        var args = that.get_primary_key();
+    that.add_fields_to_command = function(update_info, command) {
 
-        var command = IPA.command({
-            entity: that.entity.name,
-            method: 'mod',
-            args: args,
-            options: {
-                all: true,
-                rights: true
-            },
-            on_success: on_success,
-            on_error: on_error
-        });
+        for (var i=0; i < update_info.fields.length; i++) {
+            var field_info = update_info.fields[i];
+            var values = field_info.field.save();
+            IPA.command_builder.add_field_option(
+                command,
+                field_info.field.name,
+                field_info.field.param_info,
+                values,
+                field_info.field.join);
+        }
+    };
 
-        var record = {};
-        that.save(record);
+    that.add_record_to_command = function(record, sections, command) {
 
-        var sections = that.sections.values;
         for (var i=0; i<sections.length; i++) {
             var section = sections[i];
 
@@ -659,30 +666,129 @@ IPA.details_facet = function(spec) {
                 var values = record[field.name];
                 if (!values) continue;
 
-                var metadata = field.metadata;
-                if (metadata) {
-                    if (metadata.primary_key) continue;
-                    if (values.length === 1) {
-                        command.set_option(field.name, values[0]);
-                    } else if (field.join) {
-                        command.set_option(field.name, values.join(','));
-                    } else {
-                        command.set_option(field.name, values);
-                    }
-                } else {
-                    if (values.length) {
-                        command.add_option('setattr', field.name+'='+values[0]);
-                    } else {
-                        command.add_option('setattr', field.name+'=');
-                    }
-                    for (var k=1; k<values.length; k++) {
-                        command.add_option('addattr', field.name+'='+values[k]);
-                    }
-                }
+                IPA.command_builder.add_field_option(
+                    command,
+                    field.name,
+                    field.metadata,
+                    values,
+                    field.join);
+
             }
         }
+    };
+
+    that.create_standard_update_command = function(on_win, on_fail) {
+
+        var args = that.get_primary_key();
+        var command = IPA.command({
+            entity: that.entity.name,
+            method: that.update_command_name,
+            args: args,
+            options: {
+                all: true,
+                rights: true
+            },
+            on_success: on_win,
+            on_error: on_fail
+        });
+
+        var record = {};
+        that.save(record);
+
+        //set command options
+        that.add_record_to_command(record, that.sections.values, command);
+
+        return command;
+    };
+
+    that.create_fields_update_command = function(update_info, on_win, on_fail) {
+
+        var args = that.get_primary_key();
+        var command = IPA.command({
+            entity: that.entity.name,
+            method: that.update_command_name,
+            args: args,
+            options: {
+                all: true,
+                rights: true
+            },
+            on_success: on_win,
+            on_error: on_fail
+        });
+
+        //set command options
+        that.add_fields_to_command(update_info, command);
+
+        return command;
+    };
+
+    that.create_batch_update_command = function(update_info, on_win, on_fail) {
+
+        var batch = IPA.batch_command({
+            'name': that.entity.name + '_details_update',
+            'on_success': on_win,
+            'on_error': on_fail
+        });
+
+        var new_update_info = IPA.update_info_builder.copy(update_info);
+
+        if (update_info.fields.length > 0) {
+            new_update_info.append_command(
+                that.create_fields_update_command(update_info),
+                IPA.config.default_priority);
+        }
+
+        new_update_info.commands.sort(function(a, b) {
+            return a.priority - b.priority;
+        });
+
+        for (var i=0; i < new_update_info.commands.length; i++) {
+            batch.add_command(new_update_info.commands[i].command);
+        }
+
+        return batch;
+    };
+
+    that.show_validation_error = function() {
+        var dialog = IPA.message_dialog({
+            title: IPA.messages.dialogs.validation_title,
+            message: IPA.messages.dialogs.validation_message
+        });
+        dialog.open();
+    };
+
+    that.update = function(on_win, on_fail) {
 
-        //alert(JSON.stringify(command.to_json()));
+        var on_success = function(data, text_status, xhr) {
+            that.on_update_success(data, text_status, xhr);
+            if (on_win) on_win.call(this, data, text_status, xhr);
+        };
+
+        var on_error = function(xhr, text_status, error_thrown) {
+            that.on_update_error(xhr, text_status, error_thrown);
+            if (on_fail) on_fail.call(this, xhr, text_status, error_thrown);
+        };
+
+        var command;
+
+        if(that.command_mode === 'info') {
+
+            var update_info = that.get_update_info();
+
+            if (update_info.commands.length <= 0) {
+                //normal command
+                command = that.create_fields_update_command(update_info,
+                                                            on_success,
+                                                            on_error);
+            } else {
+                //batch command
+                command = that.create_batch_update_command(update_info,
+                                                           on_success,
+                                                           on_error);
+            }
+        } else {
+            command = that.create_standard_update_command(on_success, on_error);
+        }
 
         if (that.pre_execute_hook){
             that.pre_execute_hook(command);
@@ -719,7 +825,7 @@ IPA.details_facet = function(spec) {
 
         command.on_error = that.on_error;
 
-        if (that.pre_execute_hook){
+        if (that.pre_execute_hook) {
             that.pre_execute_hook(command);
         }
 
@@ -735,6 +841,22 @@ IPA.details_facet = function(spec) {
         }
     };
 
+    that.get_update_info = function() {
+
+        var update_info = IPA.update_info_builder.new_update_info();
+
+        for (var i = 0; i < that.sections.length; i++) {
+            var section = that.sections.values[i];
+            if(section.get_update_info) {
+                update_info = IPA.update_info_builder.merge(
+                    update_info,
+                    section.get_update_info());
+            }
+        }
+
+        return update_info;
+    };
+
     that.add_sections(spec.sections);
 
     that.details_facet_create_content = that.create_content;
@@ -743,3 +865,112 @@ IPA.details_facet = function(spec) {
     return that;
 };
 
+IPA.update_info = function(spec) {
+
+    var that = {};
+
+    that.fields = spec.fields || [];
+    that.commands = spec.commands || [];
+
+    that.append_field = function(field, value) {
+        that.fields.push(IPA.update_info_builder.new_field_info(field, value));
+    };
+
+    that.append_command = function (command, priority) {
+        that.commands.push(IPA.update_info_builder.new_command_info(command,
+                                                                    priority));
+    };
+
+    return that;
+};
+
+IPA.command_info = function(spec) {
+
+    var that = {};
+
+    that.command = spec.command;
+    that.priority = spec.priority || IPA.config.default_priority;
+
+    return that;
+};
+
+IPA.field_info = function(spec) {
+
+    var that = {};
+
+    that.field = spec.field;
+    that.value = spec.value;
+
+    return that;
+};
+
+IPA.update_info_builder = function() {
+
+    var that = {};
+
+    that.new_update_info = function (fields, commands) {
+        return IPA.update_info({
+            fields: fields,
+            commands: commands
+        });
+    };
+
+    that.new_field_info = function(field, value) {
+        return IPA.field_info({
+            field: field,
+            value: value
+        });
+    };
+
+    that.new_command_info = function(command, priority) {
+        return IPA.command_info({
+            command: command,
+            priority: priority
+        });
+    };
+
+    that.merge = function(a, b) {
+        return that.new_update_info(
+            a.fields.concat(b.fields),
+            a.commands.concat(b.commands));
+    };
+
+    that.copy = function(original) {
+        return that.new_update_info(
+            original.fields.concat([]),
+            original.commands.concat([]));
+    };
+
+    return that;
+}();
+
+IPA.command_builder = function() {
+
+    var that = {};
+
+    that.add_field_option = function(command, field_name, param_info, values, join) {
+        if (!values) return;
+
+        if (param_info) {
+            if (param_info.primary_key) return;
+            if (values.length === 1) {
+                command.set_option(field_name, values[0]);
+            } else if (join) {
+                command.set_option(field_name, values.join(','));
+            } else {
+                command.set_option(field_name, values);
+            }
+        } else {
+            if (values.length) {
+                command.add_option('setattr', field_name+'='+values[0]);
+            } else {
+                command.add_option('setattr', field_name+'=');
+            }
+            for (var k=1; k<values.length; k++) {
+                command.add_option('addattr', field_name+'='+values[k]);
+            }
+        }
+    };
+
+    return that;
+}();
\ No newline at end of file
diff --git a/install/ui/ipa.js b/install/ui/ipa.js
index 0ce783dbcf6a6607f7b00056ca47b72509854731..a8c65fd93290b4e8db010270243f55843f3193a6 100644
--- a/install/ui/ipa.js
+++ b/install/ui/ipa.js
@@ -189,14 +189,14 @@ var IPA = ( function () {
                 entity = factory();
                 that.add_entity(entity);
             } catch (e) {
-                if (e.expected){
+                if (e.expected) {
                     /*expected exceptions thrown by builder just mean that
                       entities are not to be registered. */
                     return null;
                 }
-                if (e.message){
+                if (e.message) {
                     alert(e.message);
-                }else{
+                } else {
                     alert(e);
                 }
                 return null;
@@ -1071,3 +1071,7 @@ IPA.error_list = function() {
     that.clear();
     return that;
 };
+
+IPA.config = {
+    default_priority: 500
+};
\ No newline at end of file
diff --git a/install/ui/widget.js b/install/ui/widget.js
index fb87c89935d3c72d444a08e18580bb099134bc3f..c3260659377def163242a78c514f912b79b89781 100644
--- a/install/ui/widget.js
+++ b/install/ui/widget.js
@@ -59,6 +59,8 @@ IPA.widget = function(spec) {
 
     that.metadata = spec.metadata;
 
+    that.priority = spec.priority;
+
     that.values = [];
     that.dirty = false;
     that.valid = true;
@@ -290,6 +292,17 @@ IPA.widget = function(spec) {
     that.update = function() {
     };
 
+    that.get_update_info = function() {
+
+        var update_info = IPA.update_info_builder.new_update_info();
+        if(that.is_dirty()) {
+            update_info.fields.push(IPA.update_info_builder.new_field_info(
+                that,
+                that.save()));
+        }
+        return update_info;
+    };
+
     /**
      * This function saves the values entered in the UI.
      * It returns the values in an array, or null if
@@ -2140,4 +2153,4 @@ IPA.html_util = function() {
     };
 
     return that;
-}();
+}();
\ No newline at end of file
-- 
1.7.6.4

_______________________________________________
Freeipa-devel mailing list
Freeipa-devel@redhat.com
https://www.redhat.com/mailman/listinfo/freeipa-devel

Reply via email to