On 06/03/2016 03:10 PM, Petr Vobornik wrote:
On 06/02/2016 01:40 PM, Pavel Vomacka wrote:
Hello,

please review my patches which add webui for server roles.

Did not test yet. I'm waiting for rebase of backend.

Patch 36: ACK (assuming it works when ^^ is available)

Patch 37:

1. typo: 'overriden' - twice
Fixed.

2. 'create_column_link' is a bad name for the method. The method doesn't
create a column link. It is a link's click handler. So the name should
be e.g. on_column_link_click
Yes, this is better. Fixed.
Patch 38:

1. in serverroles_nested_search_facet wouldn't it be better to override
only get_refresh_command_options and maybe get_refresh_command_args
instead of full create_refresh_command?

Fixed.

Attached the whole patchset with edited patches.

--
Pavel^3 Vomacka
From 142e46045f6fe4f64ce20a1b822508fece767579 Mon Sep 17 00:00:00 2001
From: Pavel Vomacka <pvoma...@redhat.com>
Date: Thu, 2 Jun 2016 13:07:00 +0200
Subject: [PATCH 1/3] Association table can be read only

When it is read only it does not show Add and Delete buttons.

Part of: https://fedorahosted.org/freeipa/ticket/5906
---
 install/ui/src/freeipa/association.js | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/install/ui/src/freeipa/association.js b/install/ui/src/freeipa/association.js
index abb032fbb73b33553f38e0fcd78fafbaf72ab095..7579bb095842b80422c94cbe06eb2c8225a2944d 100644
--- a/install/ui/src/freeipa/association.js
+++ b/install/ui/src/freeipa/association.js
@@ -428,6 +428,7 @@ IPA.association_table_widget = function (spec) {
     that.add_method = spec.add_method || 'add_member';
     that.remove_method = spec.remove_method || 'remove_member';
 
+    that.read_only = spec.read_only === undefined ? false : spec.read_only;
     that.add_title = text.get(spec.add_title || '@i18n:association.add.member');
     that.remove_title = text.get(spec.remove_title || '@i18n:association.remove.member');
 
@@ -501,6 +502,8 @@ IPA.association_table_widget = function (spec) {
 
         that.table_create(container);
 
+        if (that.read_only) return;
+
         that.remove_button = IPA.button_widget({
             name: 'remove',
             label: '@i18n:buttons.remove',
-- 
2.5.5

From e5891c1955d48b1236d2cca47f6b9c8ec687e9ba Mon Sep 17 00:00:00 2001
From: Pavel Vomacka <pvoma...@redhat.com>
Date: Thu, 2 Jun 2016 13:08:27 +0200
Subject: [PATCH 1/2] Extend table facet

There is new attribute of table facet which allows to set which collumn of
table will be its primary key. This patch also move some code into separate
method - it will be easier to overide some functionality in child classes.

Part of: https://fedorahosted.org/freeipa/ticket/5906
---
 install/ui/src/freeipa/facet.js | 71 +++++++++++++++++++++++++++++++++--------
 1 file changed, 57 insertions(+), 14 deletions(-)

diff --git a/install/ui/src/freeipa/facet.js b/install/ui/src/freeipa/facet.js
index 9d71487c970368279dc2812b14d8171cf795c8bc..70602667cb0cd016326d53c6071ab17bc4e18820 100644
--- a/install/ui/src/freeipa/facet.js
+++ b/install/ui/src/freeipa/facet.js
@@ -360,6 +360,13 @@ exp.facet = IPA.facet = function(spec, no_init) {
     that.state = new FacetState();
 
 
+    /**
+     * Sets the name of attribute which will be used as primary key in case
+     * that primary key is missing in metadata.
+     * @type {String}
+     */
+    that.primary_key_name = spec.primary_key_name;
+
     that.get_full_name = function() {
         if (that.entity) {
             return that.entity.create_facet_type(that.name);
@@ -2011,6 +2018,23 @@ exp.table_facet = IPA.table_facet = function(spec, no_init) {
     };
 
     /**
+     * Method which is called before adding the record into array which will be
+     * displayed. This is place where filters can be implemented. If this
+     * method returns true then the record will be shown in table. if returns
+     * false then the record won't be shown.
+     *
+     * It is created to be overridden by child classes.
+     *
+     * @param records_map {Array} array of already added entries
+     * @param pkey {string} primary_key
+     * @param record {Object} result from API call response
+     * @return {boolean} true when the record should be shown, otherwise false
+     */
+    that.filter_records = function(records_map, pkey, record) {
+        return true;
+    };
+
+    /**
      * Create a map with records as values and pkeys as keys
      *
      * Extracts records from data, where data originates from RPC command.
@@ -2024,13 +2048,16 @@ exp.table_facet = IPA.table_facet = function(spec, no_init) {
         var records_map = $.ordered_map();
 
         var result = data.result.result;
-        var pkey_name = that.managed_entity.metadata.primary_key;
+        var pkey_name = that.managed_entity.metadata.primary_key ||
+                                                        that.primary_key_name;
         var adapter = builder.build('adapter', 'adapter', {context: that});
 
         for (var i=0; i<result.length; i++) {
             var record = result[i];
             var pkey = adapter.load(record, pkey_name)[0];
-            records_map.put(pkey, record);
+            if (that.filter_records(records_map, pkey, record)) {
+                records_map.put(pkey, record);
+            }
         }
 
         return records_map;
@@ -2239,6 +2266,31 @@ exp.table_facet = IPA.table_facet = function(spec, no_init) {
         return that.table.get_selected_values();
     };
 
+
+    /**
+     *
+     * Method which will be called after clicking on pkey in table.
+     *
+     * It can be overridden by child classes for changing afterclick behavior.
+     *
+     * @param {String} value automatically filed by clicking
+     * @param {entity.entity} table entity
+     * @return {boolean} false
+     */
+    that.on_column_link_click = function(value, entity) {
+        var pkeys = [value];
+
+        // for nested entities
+        var containing_entity = entity.get_containing_entity();
+        if (containing_entity && that.entity.name === containing_entity.name) {
+            pkeys = that.get_pkeys();
+            pkeys.push(value);
+        }
+
+        navigation.show_entity(entity.name, that.details_facet_name, pkeys);
+        return false;
+    };
+
     /**
      * Create table
      *
@@ -2265,24 +2317,15 @@ exp.table_facet = IPA.table_facet = function(spec, no_init) {
             var column = columns[i];
 
             var metadata = IPA.get_entity_param(entity.name, column.name);
-            column.primary_key = metadata && metadata.primary_key;
+            column.primary_key = metadata && metadata.primary_key ||
+                        (that.primary_key_name === column.param);
             if (column.primary_key) {
                 column.link = column.link === undefined ? true : column.link;
             }
 
             if (column.link && column.primary_key) {
                 column.link_handler = function(value) {
-                    var pkeys = [value];
-
-                    // for nested entities
-                    var containing_entity = entity.get_containing_entity();
-                    if (containing_entity && that.entity.name === containing_entity.name) {
-                        pkeys = that.get_pkeys();
-                        pkeys.push(value);
-                    }
-
-                    navigation.show_entity(entity.name, that.details_facet_name, pkeys);
-                    return false;
+                    that.on_column_link_click(value, entity);
                 };
             }
 
-- 
2.5.5

From f5d63d080c1dc7b2f842c27ba7bb03cb3ba792f5 Mon Sep 17 00:00:00 2001
From: Pavel Vomacka <pvoma...@redhat.com>
Date: Thu, 2 Jun 2016 13:10:07 +0200
Subject: [PATCH 2/2] Add server roles on topology page

Adds new tab on topology page which shows server roles. Also extends
server details page and server config page (setting of ca renewal server).

https://fedorahosted.org/freeipa/ticket/5906
---
 install/ui/src/freeipa/navigation/menu_spec.js |   5 +
 install/ui/src/freeipa/serverconfig.js         |   7 ++
 install/ui/src/freeipa/topology.js             | 121 ++++++++++++++++++++++++-
 3 files changed, 132 insertions(+), 1 deletion(-)

diff --git a/install/ui/src/freeipa/navigation/menu_spec.js b/install/ui/src/freeipa/navigation/menu_spec.js
index fb64ccaea56cabdb6addb28543d3f968a746018b..784ef78d9e0591b3c440be6baf89833c450eb9da 100644
--- a/install/ui/src/freeipa/navigation/menu_spec.js
+++ b/install/ui/src/freeipa/navigation/menu_spec.js
@@ -221,6 +221,11 @@ var nav = {};
                             hidden: true
                         },
                         {
+                            entity: 'server_role',
+                            facet: 'search',
+                            hidden: true
+                        },
+                        {
                             entity: 'domainlevel',
                             facet: 'details',
                             hidden: true
diff --git a/install/ui/src/freeipa/serverconfig.js b/install/ui/src/freeipa/serverconfig.js
index 70bb9574b8368d6a294dc171fdea2d03dfe56cab..4ff3e7eb961686a2906379e81100a48a5e41bfb7 100644
--- a/install/ui/src/freeipa/serverconfig.js
+++ b/install/ui/src/freeipa/serverconfig.js
@@ -95,6 +95,13 @@ return {
                         {
                             $type: 'multivalued',
                             name: 'ipauserobjectclasses'
+                        },
+                        {
+                            $type: 'entity_select',
+                            name: 'ipacarenewalmaster',
+                            other_entity: 'server',
+                            other_field: 'cn',
+                            flags: ['w_if_no_aci']
                         }
                     ]
                 },
diff --git a/install/ui/src/freeipa/topology.js b/install/ui/src/freeipa/topology.js
index c26dc685328904ed893c960b6b4b0981cd9d28ce..b33bf0ea464f785af99efb9f85ab7edd7ae8c90a 100644
--- a/install/ui/src/freeipa/topology.js
+++ b/install/ui/src/freeipa/topology.js
@@ -50,6 +50,7 @@ var topology = IPA.topology = {
         facets: {
             suffix_search: 'topologysuffix_search',
             server_search: 'server_search',
+            server_role_search: 'server_role_search',
             domainlevel: 'domainlevel_details',
             topologygraph: 'topology-graph'
         }
@@ -221,7 +222,15 @@ return {
                         { name: 'cn', read_only: true },
                         { name: 'ipamindomainlevel', read_only: true },
                         { name: 'ipamaxdomainlevel', read_only: true },
-                        { $type: 'multivalued', name: 'iparepltopomanagedsuffix_topologysuffix', read_only: true }
+                        { $type: 'multivalued', name: 'iparepltopomanagedsuffix_topologysuffix', read_only: true },
+                        {
+                            $type: 'association_table',
+                            other_entity: 'server_role',
+                            name: 'servrole',
+                            footer: false,
+                            read_only: true,
+                            selectable: false
+                        }
                     ]
                 }
             ]
@@ -229,6 +238,108 @@ return {
     ]
 };};
 
+
+var make_serverroles_spec = function() {
+return {
+    name: 'server_role',
+    facet_groups: [ 'role_servers' ],
+    facets: [
+        {
+            $factory: topology.serverroles_search_facet,
+            $type: 'search',
+            primary_key_name: 'servrole',
+            search_all_entries: true,
+            no_update: true,
+            selectable: false,
+            disable_facet_tabs: false,
+            tabs_in_sidebar: true,
+            tab_label: '@mo:server_role.label',
+            facet_groups: [topology.search_facet_group],
+            facet_group: 'search',
+            columns: [
+                'servrole',
+                'status'
+            ]
+        },
+        {
+            $factory: topology.serverroles_nested_search_facet,
+            $type: 'nested_search',
+            search_all_entries: true,
+            primary_key_name: 'server',
+            no_update: true,
+            selectable: false,
+            nested_entity: 'server_role',
+            facet_group: 'role_servers',
+            label: '@mo:server_role.label_singular',
+            columns: [
+                'server',
+                'status'
+            ]
+        }
+    ]
+};};
+
+topology.serverroles_search_facet = function(spec) {
+
+    spec = spec || {};
+
+    var that = IPA.search_facet(spec);
+
+    that.filter_records = function(records_map, pkey, record) {
+
+        var stored_record = records_map.get(pkey);
+        if (!stored_record) return true;
+
+        // set priority to all possible values. Value with higher priority
+        // will overwrite a value with lower prio.
+        var priority_map = {
+            absent: 0,
+            configured: 1,
+            enabled: 2
+        };
+
+        var priority_old = priority_map[stored_record.status];
+        var priority_new = priority_map[record.status];
+        return priority_new >= priority_old;
+    };
+
+    return that;
+};
+
+topology.serverroles_nested_search_facet = function(spec) {
+
+    spec = spec || {};
+
+    var that = IPA.nested_search_facet(spec);
+
+    that.get_refresh_command_args = function() {
+        // We need to have refresh command without arguments. There is a argument
+        // value only in case of filtering.
+        var filter = that.state.filter || '';
+        var args = [];
+        args.push(filter);
+        return args;
+    };
+
+    that.get_refresh_command_options = function() {
+        return { 'servrole': that.get_pkey() };
+    };
+
+    that.on_column_link_click = function(value, entity) {
+        var pkeys = [value];
+
+        navigation.show_entity('server', that.details_facet_name, pkeys);
+        return false;
+    };
+
+    that.filter_records = function(records_map, pkey, record) {
+        // Return false when the status is 'absent'
+        return record.status !== 'absent';
+    };
+
+    return that;
+};
+
 var make_domainlevel_spec = function() {
 return {
     name: 'domainlevel',
@@ -965,6 +1076,13 @@ topology.segment_spec = make_segment_spec();
 topology.server_spec = make_server_spec();
 
 /**
+ * IPA server roles entity specification object
+ * @member topology
+ */
+topology.serverroles_spec = make_serverroles_spec();
+
+
+/**
  * Domain Level entity specification object
  * @member topology
  */
@@ -984,6 +1102,7 @@ topology.register = function() {
     e.register({type: 'topologysuffix', spec: topology.suffix_spec});
     e.register({type: 'topologysegment', spec: topology.segment_spec});
     e.register({type: 'server', spec: topology.server_spec});
+    e.register({type: 'server_role', spec: topology.serverroles_spec});
     e.register({type: 'domainlevel', spec: topology.domainlevel_spec});
 
     a.register('domainlevel_set', topology.domainlevel_set_action);
-- 
2.5.5

-- 
Manage your subscription for the Freeipa-devel mailing list:
https://www.redhat.com/mailman/listinfo/freeipa-devel
Contribute to FreeIPA: http://www.freeipa.org/page/Contribute/Code

Reply via email to