The dialogs and details pages have been modified to use the * symbol
to mark required fields. The automount map and the DNS zone dialogs
have been modified to update the required fields according to the
input type.

Ticket #1696

--
Endi S. Dewata
From 1320f4fc2aee116909d13b2dc388b9642815a7d8 Mon Sep 17 00:00:00 2001
From: Endi S. Dewata <edew...@redhat.com>
Date: Wed, 19 Oct 2011 18:11:09 -0200
Subject: [PATCH] Fixed inconsistent required/optional attributes.

The dialogs and details pages have been modified to use the * symbol
to mark required fields. The automount map and the DNS zone dialogs
have been modified to update the required fields according to the
input type.

Ticket #1696
---
 install/ui/aci.js                  |    6 +-
 install/ui/add.js                  |  136 ++++++++++++----------
 install/ui/automount.js            |   28 +++--
 install/ui/details.js              |   49 +++++----
 install/ui/dns.js                  |  222 ++++++++++++++++--------------------
 install/ui/hbac.js                 |    3 +-
 install/ui/host.js                 |   12 +-
 install/ui/ipa.css                 |    7 +-
 install/ui/policy.js               |    8 +-
 install/ui/service.js              |   63 ++++++-----
 install/ui/sudo.js                 |    3 +-
 install/ui/test/data/ipa_init.json |    2 +-
 install/ui/test/details_tests.js   |    5 +-
 install/ui/user.js                 |    5 +-
 install/ui/widget.js               |   34 ++++--
 ipalib/plugins/internal.py         |    2 +-
 16 files changed, 307 insertions(+), 278 deletions(-)

diff --git a/install/ui/aci.js b/install/ui/aci.js
index 8dcb540b6a030222136e95d5d01b5a11c29acd7f..7a331118afb05df720429f004202b410ed29eac5 100644
--- a/install/ui/aci.js
+++ b/install/ui/aci.js
@@ -35,11 +35,7 @@ IPA.entity_factories.permission = function() {
             {
                 name: 'identity',
                 fields: [
-                    {
-                        factory: IPA.text_widget,
-                        name: 'cn',
-                        read_only: true
-                    }
+                    'cn'
                 ]
             },
             {
diff --git a/install/ui/add.js b/install/ui/add.js
index 17418aaba4f0fe623483323a13c3d5cd608f4c71..3091c921b5fce5235d214b1654ae5cfec0e4ca25 100644
--- a/install/ui/add.js
+++ b/install/ui/add.js
@@ -35,7 +35,72 @@ IPA.add_dialog = function (spec) {
     that.retry = typeof spec.retry !== 'undefined' ? spec.retry : true;
     that.command = null;
 
-    function show_edit_page(entity,result){
+    that.show_edit_page = spec.show_edit_page || show_edit_page;
+
+    var init = function() {
+        that.create_button({
+            name: 'add',
+            label: IPA.messages.buttons.add,
+            click: function() {
+                that.hide_message();
+                that.add(
+                    function(data, text_status, xhr) {
+                        var facet = IPA.current_entity.get_facet();
+                        var table = facet.table;
+                        table.refresh();
+                        that.close();
+                    },
+                    that.on_error);
+            }
+        });
+
+        that.create_button({
+            name: 'add_and_add_another',
+            label: IPA.messages.buttons.add_and_add_another,
+            click: function() {
+                that.hide_message();
+                that.add(
+                    function(data, text_status, xhr) {
+                        var label = that.entity.metadata.label_singular;
+                        var message = IPA.messages.dialogs.add_confirmation;
+                        message = message.replace('${entity}', label);
+                        that.show_message(message);
+
+                        var facet = IPA.current_entity.get_facet();
+                        var table = facet.table;
+                        table.refresh();
+                        that.reset();
+                    },
+                    that.on_error);
+            }
+        });
+
+        that.create_button({
+            name: 'add_and_edit',
+            label: IPA.messages.buttons.add_and_edit,
+            click: function() {
+                that.hide_message();
+                that.add(
+                    function(data, text_status, xhr) {
+                        that.close();
+                        var result = data.result.result;
+                        that.show_edit_page(that.entity, result);
+                    },
+                    that.on_error);
+            }
+        });
+
+        that.create_button({
+            name: 'cancel',
+            label: IPA.messages.buttons.cancel,
+            click: function() {
+                that.hide_message();
+                that.close();
+            }
+        });
+    };
+
+    function show_edit_page(entity,result) {
         var pkey_name = entity.metadata.primary_key;
         var pkey = result[pkey_name];
         if (pkey instanceof Array) {
@@ -44,8 +109,6 @@ IPA.add_dialog = function (spec) {
         IPA.nav.show_entity_page(that.entity, 'default', pkey);
     }
 
-    that.show_edit_page = spec.show_edit_page || show_edit_page;
-
     that.add = function(on_success, on_error) {
 
         var pkey_name = that.entity.metadata.primary_key;
@@ -110,67 +173,18 @@ IPA.add_dialog = function (spec) {
         command.execute();
     };
 
-    /*dialog initialization*/
-    that.create_button({
-        name: 'add',
-        label: IPA.messages.buttons.add,
-        click: function() {
-            that.hide_message();
-            that.add(
-                function(data, text_status, xhr) {
-                    var facet = IPA.current_entity.get_facet();
-                    var table = facet.table;
-                    table.refresh();
-                    that.close();
-                },
-                that.on_error);
-        }
-    });
+    that.create = function() {
+        that.dialog_create();
 
-    that.create_button({
-        name: 'add_and_add_another',
-        label: IPA.messages.buttons.add_and_add_another,
-        click: function() {
-            that.hide_message();
-            that.add(
-                function(data, text_status, xhr) {
-                    var label = that.entity.metadata.label_singular;
-                    var message = IPA.messages.dialogs.add_confirmation;
-                    message = message.replace('${entity}', label);
-                    that.show_message(message);
+        $('<div/>', {
+            text: IPA.messages.dialogs.required
+        }).appendTo(that.container);
+    };
 
-                    var facet = IPA.current_entity.get_facet();
-                    var table = facet.table;
-                    table.refresh();
-                    that.reset();
-                },
-                that.on_error);
-        }
-    });
+    // methods that should be invoked by subclasses
+    that.add_dialog_create = that.create;
 
-    that.create_button({
-        name: 'add_and_edit',
-        label: IPA.messages.buttons.add_and_edit,
-        click: function() {
-            that.hide_message();
-            that.add(
-                function(data, text_status, xhr) {
-                    that.close();
-                    var result = data.result.result;
-                    that.show_edit_page(that.entity, result);
-                },
-                that.on_error);
-        }
-    });
-
-    that.create_button({
-        name: 'cancel',
-        label: IPA.messages.buttons.cancel,
-        click: function() {
-            that.hide_message();
-            that.close();
-        }
-    });
+    init();
 
     return that;
 };
diff --git a/install/ui/automount.js b/install/ui/automount.js
index 89b0f6b7eff2988a5f2efcac2358323ee956f767..4428ded8b041f0ffb3097134c035863a2ba48da9 100644
--- a/install/ui/automount.js
+++ b/install/ui/automount.js
@@ -144,17 +144,17 @@ IPA.entity_factories.automountkey = function() {
         entity({ name: 'automountkey' }).
         containing_entity('automountmap').
         details_facet({
-            sections:[
+            sections: [
                 {
                     name:'identity',
                     label: IPA.messages.details.identity,
-                    fields:[
+                    fields: [
                         {
-                            factory: IPA.text_widget,
-                            read_only: true,
-                            name:   'automountkey'
+                            name: 'automountkey',
+                            read_only: true
                         },
-                        'automountinformation']
+                        'automountinformation'
+                    ]
                 }
             ],
             disable_breadcrumb: false,
@@ -224,20 +224,30 @@ IPA.automountmap_adder_dialog = function(spec) {
     var that = IPA.add_dialog(spec);
 
     that.create = function() {
-        that.dialog_create();
+        that.add_dialog_create();
 
         var method_field = that.get_field('method');
+        var indirect_section = that.get_section('indirect');
+        var key_field = that.get_field('key');
 
         var direct_input = $('input[value="add"]', method_field.container);
         direct_input.change(function() {
             that.method = 'add';
-            that.get_section('indirect').set_visible(false);
+
+            key_field.required = false;
+
+            indirect_section.set_visible(false);
+            indirect_section.create_field_label(key_field);
         });
 
         var indirect_input = $('input[value="add_indirect"]', method_field.container);
         indirect_input.change(function() {
             that.method = 'add_indirect';
-            that.get_section('indirect').set_visible(true);
+
+            key_field.required = true;
+
+            indirect_section.set_visible(true);
+            indirect_section.create_field_label(key_field);
         });
 
         direct_input.click();
diff --git a/install/ui/details.js b/install/ui/details.js
index 1e4a9eb5f1148cb109a89d0affd6aee3c4c6eefd..2effed0a2014a3e3cd5ce5ca6fc352febcc87fc5 100644
--- a/install/ui/details.js
+++ b/install/ui/details.js
@@ -234,48 +234,55 @@ IPA.details_table_section = function(spec) {
             var tr = $('<tr/>').appendTo(table);
 
             var td = $('<td/>', {
-                'class': 'section-cell-label'
+                'class': 'section-cell-label',
+                title: field.label
             }).appendTo(tr);
 
-            $('<label/>', {
+            field.label_container = $('<label/>', {
                 name: field.name,
-                title: field.label,
-                'class': 'field-label',
-                text: field.label+':'
+                'class': 'field-label'
             }).appendTo(td);
 
+            that.create_field_label(field);
+
             td = $('<td/>', {
-                'class': 'section-cell-field'
+                'class': 'section-cell-field',
+                title: field.label
             }).appendTo(tr);
 
             var field_container = $('<div/>', {
                 name: field.name,
-                title: field.label,
                 'class': 'field'
             }).appendTo(td);
 
             field.create(field_container);
+        }
+    };
+
+    that.load = function(record) {
+        that.section_load(record);
 
-            if (field.optional) {
-                field_container.css('display', 'none');
+        var fields = that.fields.values;
+        for (var j=0; j<fields.length; j++) {
+            var field = fields[j];
+            that.create_field_label(field);
+        }
+    };
 
-                var link = $('<a/>', {
-                    text: IPA.messages.widget.optional,
-                    href: ''
-                }).appendTo(td);
+    that.create_field_label = function(field) {
 
-                link.click(function(field_container, link) {
-                    return function() {
-                        field_container.css('display', 'inline');
-                        link.css('display', 'none');
-                        return false;
-                    };
-                }(field_container, link));
-            }
+        if (!field.label_container) return;
+
+        var label = field.label+':';
+        if (field.is_required()) {
+            label = label+'*';
         }
+
+        field.label_container.text(label);
     };
 
     that.table_section_create = that.create;
+    that.table_section_load = that.load;
 
     return that;
 };
diff --git a/install/ui/dns.js b/install/ui/dns.js
index 60505d999d78b8d22331b2a01cb0543cc613f548..a3c4911a6aee4955e15fa15ba5b52c60f2b8f230 100644
--- a/install/ui/dns.js
+++ b/install/ui/dns.js
@@ -106,21 +106,32 @@ IPA.entity_factories.dnszone = function() {
         adder_dialog({
             factory: IPA.dnszone_adder_dialog,
             height: 300,
-            fields: [
+            sections: [
                 {
-                    name: 'idnsname',
-                    optional: true
+                    factory: IPA.dnszone_name_section,
+                    name: 'name',
+                    fields: [
+                        {
+                            name: 'idnsname',
+                            required: false
+                        },
+                        'name_from_ip'
+                    ]
                 },
-                'name_from_ip',
-                'idnssoamname',
                 {
-                    name: 'idnssoarname',
-                    optional: true
-                },
-                {
-                    factory: IPA.force_dnszone_add_checkbox_widget,
-                    name: 'force',
-                    param_info: IPA.get_method_option('dnszone_add', 'force')
+                    name: 'other',
+                    fields: [
+                        'idnssoamname',
+                        {
+                            name: 'idnssoarname',
+                            required: false
+                        },
+                        {
+                            factory: IPA.force_dnszone_add_checkbox_widget,
+                            name: 'force',
+                            param_info: IPA.get_method_option('dnszone_add', 'force')
+                        }
+                    ]
                 }
             ]
         }).
@@ -231,200 +242,163 @@ IPA.dnszone_details_facet = function(spec) {
     return that;
 };
 
-// TODO: Remove the custom create() by moving the fields into sections.
-// The idnsname and name_from_ip should be moved into a custom section.
-// The idnssoamname, idnssoarname, and force into a standard section.
-IPA.dnszone_adder_dialog = function(spec) {
+IPA.dnszone_name_section = function(spec) {
 
     spec = spec || {};
 
-    var that = IPA.add_dialog(spec);
+    var that = IPA.details_table_section(spec);
 
-    that.create = function() {
-
-        that.container.addClass('dnszone-adder-dialog');
+    that.create = function(container) {
+        that.container = container;
 
         that.message_container = $('<div/>', {
             style: 'display: none',
             'class': 'dialog-message ui-state-highlight ui-corner-all'
         }).appendTo(that.container);
 
-        var table = $('<table/>').appendTo(that.container);
+        var table = $('<table/>', {
+            'class': 'section-table'
+        }).appendTo(that.container);
 
-        var field = that.get_field('idnsname');
+        var idnsname = that.get_field('idnsname');
 
         var tr = $('<tr/>').appendTo(table);
 
         var td = $('<td/>', {
-            title: field.label
+            'class': 'section-cell-label',
+            title: idnsname.label
         }).appendTo(tr);
 
         var label = $('<label/>', {
+            name: 'idnsname',
+            'class': 'field-label',
             'for': 'dnszone-adder-dialog-idnsname-radio'
         }).appendTo(td);
 
-        that.idnsname_radio = $('<input/>', {
+        idnsname.radio = $('<input/>', {
             type: 'radio',
             id: 'dnszone-adder-dialog-idnsname-radio',
             name: 'type',
-            value: 'idnsname'
+            value: idnsname.name
         }).appendTo(label);
 
-        label.append(field.label+':');
+        idnsname.label_container = $('<span/>').appendTo(label);
+
+        that.create_field_label(idnsname);
 
         td = $('<td/>', {
-            title: field.label
+            'class': 'section-cell-field',
+            title: idnsname.label
         }).appendTo(tr);
 
         var span = $('<span/>', {
-            name: field.name
+            name: 'idnsname',
+            'class': 'field'
         }).appendTo(td);
 
-        field.create(span);
+        idnsname.create(span);
 
         var idnsname_input = $('input', span);
 
-        field = that.get_field('name_from_ip');
+        var name_from_ip = that.get_field('name_from_ip');
 
         tr = $('<tr/>').appendTo(table);
 
         td = $('<td/>', {
-            title: field.label
+            'class': 'section-cell-label',
+            title: name_from_ip.label
         }).appendTo(tr);
 
         label = $('<label/>', {
+            name: 'name_from_ip',
+            'class': 'field-label',
             'for': 'dnszone-adder-dialog-name_from_ip-radio'
         }).appendTo(td);
 
-        var name_from_ip_radio = $('<input/>', {
+        name_from_ip.radio = $('<input/>', {
             type: 'radio',
             id: 'dnszone-adder-dialog-name_from_ip-radio',
             name: 'type',
-            value: 'name_from_ip'
+            value: name_from_ip.name
         }).appendTo(label);
 
-        label.append(field.label+':');
+        name_from_ip.label_container = $('<span/>').appendTo(label);
+
+        that.create_field_label(name_from_ip);
 
         td = $('<td/>', {
-            title: field.label
+            'class': 'section-cell-field',
+            title: name_from_ip.label
         }).appendTo(tr);
 
         span = $('<span/>', {
-            name: field.name
+            name: 'name_from_ip',
+            'class': 'field'
         }).appendTo(td);
 
-        field.create(span);
+        name_from_ip.create(span);
 
         var name_from_ip_input = $('input', span);
 
-        that.idnsname_radio.click(function() {
+        idnsname.radio.click(function() {
             idnsname_input.attr('disabled', false);
             name_from_ip_input.attr('disabled', true);
+
+            idnsname.required = true;
+            name_from_ip.required = false;
+
+            that.create_field_label(idnsname);
+            that.create_field_label(name_from_ip);
+
+            name_from_ip.reset();
         });
 
-        name_from_ip_radio.click(function() {
+        name_from_ip.radio.click(function() {
             idnsname_input.attr('disabled', true);
             name_from_ip_input.attr('disabled', false);
-        });
-
-        idnsname_input.focus(function() {
-            that.idnsname_radio.attr('checked', true);
-        });
-
-        name_from_ip_input.focus(function() {
-            name_from_ip_radio.attr('checked', true);
-        });
-
-        that.idnsname_radio.click();
-
-        tr = $('<tr/>').appendTo(table);
-
-        td = $('<td/>', {
-            colspan: 2,
-            html: '&nbsp;'
-        }).appendTo(tr);
-
-        field = that.get_field('idnssoamname');
-
-        tr = $('<tr/>').appendTo(table);
-
-        td = $('<td/>', {
-            title: field.label
-        }).appendTo(tr);
-
-        label = $('<label/>', {
-            text: field.label+':'
-        }).appendTo(td);
-
-        td = $('<td/>', {
-            title: field.label
-        }).appendTo(tr);
 
-        span = $('<span/>', {
-            name: field.name
-        }).appendTo(td);
+            idnsname.required = false;
+            name_from_ip.required = true;
 
-        field.create(span);
+            that.create_field_label(idnsname);
+            that.create_field_label(name_from_ip);
 
-        field = that.get_field('idnssoarname');
-
-        tr = $('<tr/>').appendTo(table);
-
-        td = $('<td/>', {
-            title: field.label
-        }).appendTo(tr);
-
-        label = $('<label/>', {
-            text: field.label+':'
-        }).appendTo(td);
-
-        td = $('<td/>', {
-            title: field.label
-        }).appendTo(tr);
-
-        span = $('<span/>', {
-            name: field.name
-        }).appendTo(td);
-
-        field.create(span);
-
-        field = that.get_field('force');
-
-        tr = $('<tr/>').appendTo(table);
-
-        td = $('<td/>', {
-            title: field.label
-        }).appendTo(tr);
-
-        label = $('<label/>', {
-            text: field.label+':'
-        }).appendTo(td);
-
-        td = $('<td/>', {
-            title: field.label
-        }).appendTo(tr);
-
-        span = $('<span/>', {
-            name: field.name
-        }).appendTo(td);
+            idnsname.reset();
+        });
 
-        field.create(span);
+        idnsname.radio.click();
     };
 
     that.save = function(record) {
 
-        that.dialog_save(record);
+        var idnsname = that.get_field('idnsname');
+        var name_from_ip = that.get_field('name_from_ip');
+
+        if (idnsname.radio.is(':checked')) {
+            record.idnsname = idnsname.save();
 
-        if (that.idnsname_radio.is(':checked')) {
-            delete record.name_from_ip;
         } else {
-            delete record.idnsname;
+            record.name_from_ip = name_from_ip.save();
         }
     };
 
     return that;
 };
 
+IPA.dnszone_adder_dialog = function(spec) {
+
+    spec = spec || {};
+
+    var that = IPA.add_dialog(spec);
+
+    that.create = function() {
+        that.add_dialog_create();
+        that.container.addClass('dnszone-adder-dialog');
+    };
+
+    return that;
+};
+
 IPA.dns_record_search_load = function (result) {
     this.table.empty();
     var normalized_record;
@@ -624,7 +598,7 @@ IPA.entity_factories.dnsrecord = function() {
                     name: 'record_data',
                     label: IPA.messages.objects.dnsrecord.data,
                     factory: IPA.text_widget,
-                    param_info: {required:true}
+                    required: true
                 }
             ]
         }).
diff --git a/install/ui/hbac.js b/install/ui/hbac.js
index c4b4877e2c2f5916ab3c926afa302f08e2927480..fb57dd1582c70aaf3c18eaee087751b1dd4c3b49 100644
--- a/install/ui/hbac.js
+++ b/install/ui/hbac.js
@@ -177,8 +177,7 @@ IPA.hbacrule_details_facet = function(spec) {
         });
 
         section.text({
-            name: 'cn',
-            read_only: true
+            name: 'cn'
         });
         section.textarea({
             name: 'description'
diff --git a/install/ui/host.js b/install/ui/host.js
index 758008892e3ba09380f241142418fc0b96e4f064..cb72b3ac1a0409399d1f3ef8aa23a77efd863f86 100644
--- a/install/ui/host.js
+++ b/install/ui/host.js
@@ -129,14 +129,14 @@ IPA.entity_factories.host = function () {
                         {
                             factory: IPA.widget,
                             name: 'fqdn',
-                            optional: true,
+                            required: false,
                             hidden: true
                         },
                         {
                             factory: IPA.text_widget,
                             name: 'hostname',
                             label: IPA.messages.objects.service.host,
-                            param_info: { required: true }
+                            required: true
                         },
                         {
                             factory: IPA.dnszone_select_widget,
@@ -144,7 +144,7 @@ IPA.entity_factories.host = function () {
                             label: IPA.metadata.objects.dnszone.label_singular,
                             editable: true,
                             empty_option: false,
-                            param_info: { required: true }
+                            required: true
                         }
                     ]
                 },
@@ -192,13 +192,13 @@ IPA.host_fqdn_section = function(spec) {
         var th = $('<th/>', {
             'class': 'hostname',
             title: hostname.label,
-            text: hostname.label
+            text: hostname.label+'*'
         }).appendTo(tr);
 
         th = $('<th/>', {
             'class': 'dnszone',
             title: dnszone.label,
-            text: dnszone.label
+            text: dnszone.label+'*'
         }).appendTo(tr);
 
         tr = $('<tr/>').appendTo(table);
@@ -261,7 +261,7 @@ IPA.host_adder_dialog = function(spec) {
     var that = IPA.add_dialog(spec);
 
     that.create = function() {
-        that.dialog_create();
+        that.add_dialog_create();
         that.container.addClass('host-adder-dialog');
     };
 
diff --git a/install/ui/ipa.css b/install/ui/ipa.css
index 3c6cc6e820555e50b72c0970fe1c53859e3ff35f..4a9d01783cbaf568a40e710856aca6342e9b5fdd 100644
--- a/install/ui/ipa.css
+++ b/install/ui/ipa.css
@@ -1256,6 +1256,10 @@ table.scrollable tbody {
     width: 100%;
 }
 
+.dnszone-adder-dialog .section-cell-label {
+    width: 180px;
+}
+
 /* Info and simple pages (not main app) */
 
 body.info-page  {
@@ -1292,5 +1296,4 @@ body.info-page  {
 .info-page .textblockkrb ul li {
     list-style-type: none;
     padding: .15em;
-}
-
+}
\ No newline at end of file
diff --git a/install/ui/policy.js b/install/ui/policy.js
index 7fbf5600c38fcf285a9794342239a7af695beed0..54321a481634e900d68e58d5f8acb38ac6819b0a 100644
--- a/install/ui/policy.js
+++ b/install/ui/policy.js
@@ -52,14 +52,16 @@ IPA.entity_factories.pwpolicy = function() {
                 }]}).
         standard_association_facets().
         adder_dialog({
-            fields:[
+            fields: [
                 {
                     factory: IPA.entity_select_widget,
                     name: 'cn',
                     other_entity: 'group',
-                    other_field: 'cn'
+                    other_field: 'cn',
+                    required: true
                 },
-                'cospriority'],
+                'cospriority'
+            ],
             height: 300
         }).
         build();
diff --git a/install/ui/service.js b/install/ui/service.js
index 912642982ed24eb24c16c165ce5f308ba715a8d5..0ac2b6bec131786ca3f0c80122e9d8483a9c8f6c 100644
--- a/install/ui/service.js
+++ b/install/ui/service.js
@@ -30,39 +30,48 @@ IPA.entity_factories.service = function() {
         search_facet({
             columns: [ 'krbprincipalname' ]
         }).
-        details_facet({sections:[
-            {
-                name: 'details',
-                fields:['krbprincipalname',
+        details_facet({
+            sections: [
+                {
+                    name: 'details',
+                    fields: [
+                        'krbprincipalname',
                         {
-                            factory:IPA.service_name_widget,
+                            factory: IPA.service_name_widget,
                             name: 'service',
                             label: IPA.messages.objects.service.service,
                             read_only: true
                         },
                         {
-                            factory:IPA.service_host_widget,
+                            factory: IPA.service_host_widget,
                             name: 'host',
                             label: IPA.messages.objects.service.host,
                             read_only: true
-                        }]
-            },
-            {
-                name: 'provisioning',
-                fields:[{
-                    factory:IPA.service_provisioning_status_widget,
-                    name: 'provisioning_status',
-                    label: IPA.messages.objects.service.status
-                }]
-            },
-            {
-                name: 'certificate',
-                fields:[{
-                    factory:IPA.service_certificate_status_widget,
-                    name: 'certificate_status',
-                    label: IPA.messages.objects.service.status
-                }]
-            }]}).
+                        }
+                    ]
+                },
+                {
+                    name: 'provisioning',
+                    fields: [
+                        {
+                            factory: IPA.service_provisioning_status_widget,
+                            name: 'provisioning_status',
+                            label: IPA.messages.objects.service.status
+                        }
+                    ]
+                },
+                {
+                    name: 'certificate',
+                    fields: [
+                        {
+                            factory: IPA.service_certificate_status_widget,
+                            name: 'certificate_status',
+                            label: IPA.messages.objects.service.status
+                        }
+                    ]
+                }
+            ]
+        }).
         association_facet({
             name: 'managedby_host',
             add_method: 'add_host',
@@ -84,7 +93,7 @@ IPA.service_add_dialog = function(spec) {
     var that = IPA.add_dialog(spec).
         field(IPA.widget({
             name: 'krbprincipalname',
-            optional: true,
+            required: false,
             entity: spec.entity,
             hidden: true
         })).
@@ -106,7 +115,7 @@ IPA.service_add_dialog = function(spec) {
             editable: true,
             size: 10,
             entity: spec.entity,
-            param_info: { required: true }
+            required: true
         })).
         field(IPA.entity_select_widget({
             name: 'host',
@@ -114,7 +123,7 @@ IPA.service_add_dialog = function(spec) {
             other_field: 'fqdn',
             entity: spec.entity,
             label: IPA.messages.objects.service.host,
-            param_info: { required: true }
+            required: true
         })).
         field(IPA.checkbox_widget({
             name: 'force',
diff --git a/install/ui/sudo.js b/install/ui/sudo.js
index cca9d3edf2f124bc5f08f7f417f8fd686e935056..226ea8db42176bf410d8ea9443f96c3d10db10bd 100644
--- a/install/ui/sudo.js
+++ b/install/ui/sudo.js
@@ -181,8 +181,7 @@ IPA.sudorule_details_facet = function(spec) {
         });
 
         section.text({
-            name: 'cn',
-            read_only: true
+            name: 'cn'
         });
         section.textarea({
             name: 'description'
diff --git a/install/ui/test/data/ipa_init.json b/install/ui/test/data/ipa_init.json
index 94467ee99210ca1288fca6353ecc99e1f915153f..5b8af9e427310e10aec6a69e8f9387562c5ce874 100644
--- a/install/ui/test/data/ipa_init.json
+++ b/install/ui/test/data/ipa_init.json
@@ -83,6 +83,7 @@
                         "redirection": "Redirection",
                         "remove_empty": "Select entries to be removed.",
                         "remove_title": "Remove ${entity}",
+                        "required": "* required",
                         "show_details": "Show details",
                         "validation_message": "Input form contains invalid or missing values.",
                         "validation_title": "Validation error"
@@ -361,7 +362,6 @@
                     "true": "True",
                     "widget": {
                         "next": "Next",
-                        "optional": "Optional field: click to show",
                         "page": "Page",
                         "prev": "Prev",
                         "undo": "undo",
diff --git a/install/ui/test/details_tests.js b/install/ui/test/details_tests.js
index 122234e78b1a604411de8412233f24478fc0a6cf..65f891b72b0ea2cb971cfeea3126b57fca83aa94 100644
--- a/install/ui/test/details_tests.js
+++ b/install/ui/test/details_tests.js
@@ -87,9 +87,10 @@ test("Testing IPA.details_section.create().", function() {
     for (var i=0; i<fields.length; i++) {
         var field = fields[i];
 
-        var field_label = $('.field-label[name='+field.name+']', container);
+        var actual_label = $('.field-label[name='+field.name+']', container).text();
+        var expected_label = field.label+':'+(field.is_required() ? '*' : '');
         same(
-            field_label.text(), field.label+':',
+            actual_label, expected_label,
             'Verifying label for field '+field.name
         );
 
diff --git a/install/ui/user.js b/install/ui/user.js
index 60958cb43cf3f853c370554162600733f3d3d90d..bfda51d84b7e34bed5f429fcdd83e0b1ea6b4e43 100644
--- a/install/ui/user.js
+++ b/install/ui/user.js
@@ -141,9 +141,8 @@ IPA.entity_factories.user = function() {
         adder_dialog({
             fields: [
                 {
-                    factory : IPA.text_widget,
-                    optional: true,
-                    name:'uid'
+                    name: 'uid',
+                    required: false
                 },
                 'givenname',
                 'sn'
diff --git a/install/ui/widget.js b/install/ui/widget.js
index e34f2ea087837fe8484ec49102645cf7e8f7f722..f99e220767696c228025d549459646f2dbd2cda5 100644
--- a/install/ui/widget.js
+++ b/install/ui/widget.js
@@ -40,7 +40,9 @@ IPA.widget = function(spec) {
 
     that.disabled = spec.disabled;
     that.hidden = spec.hidden;
-    that.optional = spec.optional || false;
+
+    // override the required flag in metadata
+    that.required = spec.required;
 
     // read_only is set when widget is created
     that.read_only = spec.read_only;
@@ -51,7 +53,7 @@ IPA.widget = function(spec) {
     that.width = spec.width;
     that.height = spec.height;
 
-    that.undo = typeof spec.undo == 'undefined' ? true : spec.undo;
+    that.undo = spec.undo === undefined ? true : spec.undo;
     that.join = spec.join;
 
     that.param_info = spec.param_info;
@@ -129,14 +131,18 @@ IPA.widget = function(spec) {
         }).appendTo(container);
     };
 
-    that.check_required = function(){
+    that.is_required = function() {
+        if (that.read_only) return false;
+        if (!that.writable) return false;
+
+        if (that.required !== undefined) return that.required;
+        return that.param_info && that.param_info.required;
+    };
+
+    that.check_required = function() {
         var values = that.save();
-        if (!values || !values.length || values[0] === '' ) {
-            if (that.param_info &&
-                that.param_info.required &&
-                !that.optional &&
-                !that.read_only &&
-                that.writable) {
+        if (!values || !values.length || values[0] === '') {
+            if (that.is_required()) {
                 that.valid = false;
                 that.show_error(IPA.messages.widget.validation.required);
                 return false;
@@ -838,6 +844,11 @@ IPA.checkbox_widget = function (spec) {
         that.input.attr('checked', value);
     };
 
+    // a checkbox will always have a value, so it's never required
+    that.is_required = function() {
+        return false;
+    };
+
     that.checkbox_save = that.save;
     that.checkbox_load = that.load;
 
@@ -1006,6 +1017,11 @@ IPA.radio_widget = function(spec) {
         }
     };
 
+    // a radio will always have a value, so it's never required
+    that.is_required = function() {
+        return false;
+    };
+
     // methods that should be invoked by subclasses
     that.radio_create = that.create;
     that.radio_save = that.save;
diff --git a/ipalib/plugins/internal.py b/ipalib/plugins/internal.py
index 8da38ee4d31e76b27065df39ca231d2c56d868c9..f26e7746905681ae64f4f0aeb97b730572721822 100644
--- a/ipalib/plugins/internal.py
+++ b/ipalib/plugins/internal.py
@@ -173,6 +173,7 @@ class i18n_messages(Command):
             "redirection": _("Redirection"),
             "remove_empty": _("Select entries to be removed."),
             "remove_title": _("Remove ${entity}"),
+            "required": _("* required"),
             "show_details": _("Show details"),
             "validation_title": _("Validation error"),
             "validation_message": _("Input form contains invalid or missing values."),
@@ -455,7 +456,6 @@ class i18n_messages(Command):
         "true": _("True"),
         "widget": {
             "next": _("Next"),
-            "optional": _("Optional field: click to show"),
             "page": _("Page"),
             "prev": _("Prev"),
             "undo": _("undo"),
-- 
1.7.5.1

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

Reply via email to