Hello,

please review attached patches.

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

--
Pavel^3 Vomacka

From 0b4898eb7eed06c4e50f6b5606736d0023a58de5 Mon Sep 17 00:00:00 2001
From: Pavel Vomacka <pvoma...@redhat.com>
Date: Thu, 11 Aug 2016 15:51:33 +0200
Subject: [PATCH 1/3] Add javascript integer validator

Javascript integer validator checks whether value entered into field is number
and is not higher than Number.MAX_SAFE_INTEGER constant.

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

diff --git a/install/ui/src/freeipa/field.js b/install/ui/src/freeipa/field.js
index d8b957f5ab28b5ee4bc4ebce2ae6f454083bc4fd..59525a46bb9d1106e89f364165d567824f37d4c5 100644
--- a/install/ui/src/freeipa/field.js
+++ b/install/ui/src/freeipa/field.js
@@ -962,6 +962,39 @@ field.validator = IPA.validator = function(spec) {
 };
 
 /**
+ * Javascript integer validator
+ *
+ * It allows to insert only integer numbers which can be safely represented by
+ * Javascript.
+ *
+ * @class
+ * @alternateClassName IPA.metadata_validator
+ * @extends IPA.validator
+ */
+ field.integer_validator = IPA.integer_validator = function(spec) {
+
+     var that = IPA.validator(spec);
+     
+     /**
+      * @inheritDoc
+      */
+     that.validate = function(value) {
+
+         if (!value.match(/^-?\d+$/)) {
+             return that.false_result(text.get('@i18n:widget.validation.integer'));
+         }
+
+         if (!Number.isSafeInteger(parseInt(value, 10))) {
+             return that.false_result(text.get('@i18n:widget.validation.unsupported'));
+         }
+
+         return that.true_result();
+     };
+
+     return that;
+ };
+
+/**
  * Metadata validator
  *
  * Validates value according to supplied metadata
@@ -1574,6 +1607,7 @@ field.register = function() {
     v.register('metadata', field.metadata_validator);
     v.register('unsupported', field.unsupported_validator);
     v.register('same_password', field.same_password_validator);
+    v.register('integer', field.integer_validator);
 
     l.register('adapter', field.Adapter);
     l.register('object_adapter', field.ObjectAdapter);
-- 
2.5.5

From ee2a7b415712db3a72d4478e42a36782d03e0ee5 Mon Sep 17 00:00:00 2001
From: Pavel Vomacka <pvoma...@redhat.com>
Date: Thu, 11 Aug 2016 15:56:01 +0200
Subject: [PATCH 2/3] Make singleton from config module

Also added general setter and getter for attributes of config.

Part of: https://fedorahosted.org/freeipa/ticket/5742
---
 install/ui/src/freeipa/config.js | 51 +++++++++++++++++++++++++++++++++++-----
 1 file changed, 45 insertions(+), 6 deletions(-)

diff --git a/install/ui/src/freeipa/config.js b/install/ui/src/freeipa/config.js
index 61922d454583c393ad68a11fcd571997b6bfab60..3bf017bdc0cab580783f7903261ebbd9a29fdc87 100644
--- a/install/ui/src/freeipa/config.js
+++ b/install/ui/src/freeipa/config.js
@@ -20,14 +20,18 @@
 
 
 
-define([], function() {
+define([
+    'dojo/_base/declare',
+    'dojo/topic'
+    ],
+    function(declare, topic) {
 
     /**
      * Application configuration
      * @class config
      * @singleton
      */
-    var config = {
+    var config = declare([], {
 
         /**
          * Selector for application container node
@@ -82,8 +86,43 @@ define([], function() {
          * Hide sections without any visible widget
          * @property {boolean}
          */
-        hide_empty_sections: true
-    };
+        hide_empty_sections: true,
 
-    return config;
-});
\ No newline at end of file
+        /**
+         * Number of lines in table on table_facets
+         * @property {Integer}
+         */
+        table_page_size: 20,
+
+        /**
+         * Genereal setter for config values.
+         * @param item_name {string}
+         * @param value
+         * @param store {Boolean} sets whether the value will be stored into
+         *                  local storage
+         */
+        set: function(item_name, value, store) {
+            if (!item_name) return;
+            this[item_name] = value;
+
+            if (store) {
+                window.localStorage.setItem(item_name, value);
+            }
+        },
+
+        /**
+         * Genereal setter for config values.
+         * @param item_name {string}
+         */
+        get: function(item_name) {
+            return this[item_name];
+        },
+
+        constructor: function() {
+            var user_limit = window.localStorage.getItem('table_page_size');
+            if (user_limit) this.table_page_size = user_limit;
+        }
+    });
+
+    return new config();
+});
-- 
2.5.5

From 9c8c20fb0898156d61f5911710a86aa796ce3c67 Mon Sep 17 00:00:00 2001
From: Pavel Vomacka <pvoma...@redhat.com>
Date: Thu, 11 Aug 2016 15:58:23 +0200
Subject: [PATCH 3/3] Add support for custom table pagination size

New customization button opens dialog with field for setting the number of lines
in tables. After saving the new value there is new topic which starts refreshing
current table facet (if shown) and set all other facets expired. Therefore all
tables are immediately regenerated.

https://fedorahosted.org/freeipa/ticket/5742
---
 install/ui/src/freeipa/Application_controller.js | 50 +++++++++++++++++++++++-
 install/ui/src/freeipa/facet.js                  | 14 ++++++-
 install/ui/src/freeipa/widget.js                 |  4 +-
 install/ui/src/freeipa/widgets/App.js            |  7 ++++
 install/ui/test/data/ipa_init.json               |  4 ++
 ipaserver/plugins/internal.py                    |  4 ++
 6 files changed, 77 insertions(+), 6 deletions(-)

diff --git a/install/ui/src/freeipa/Application_controller.js b/install/ui/src/freeipa/Application_controller.js
index 43d5409cea45e443c33d03b5f1b317df93cfcaf5..32add5f8f3d6874c1c555bf28d2b70cd54af5956 100644
--- a/install/ui/src/freeipa/Application_controller.js
+++ b/install/ui/src/freeipa/Application_controller.js
@@ -32,6 +32,8 @@ define([
         './widgets/FacetContainer',
         './ipa',
         './reg',
+        './config',
+        './widget',
         './navigation/Menu',
         './navigation/Router',
         './navigation/routing',
@@ -39,7 +41,8 @@ define([
         './plugins/load_page'
        ],
        function(declare, array, Deferred, on, topic, query, dom_class, auth,
-            JSON, App_widget, FacetContainer, IPA, reg, Menu, Router, routing, menu_spec) {
+            JSON, App_widget, FacetContainer, IPA, reg, config, widget_mod,
+            Menu, Router, routing, menu_spec) {
 
     /**
      * Application controller
@@ -110,6 +113,7 @@ define([
             on(this.app_widget, 'profile-click', this.on_profile.bind(this));
             on(this.app_widget, 'logout-click', this.on_logout.bind(this));
             on(this.app_widget, 'password-reset-click', this.on_password_reset.bind(this));
+            on(this.app_widget, 'configuration-click', this.on_configuration.bind(this));
             on(this.app_widget, 'about-click', this.on_about.bind(this));
 
             on(this.router, 'facet-show', this.on_facet_show.bind(this));
@@ -173,7 +177,6 @@ define([
 
             IPA.update_password_expiration();
 
-
             // now we are ready for displaying a facet,
             // it can match a facet if hash is set
             this.router.startup();
@@ -239,6 +242,49 @@ define([
             IPA.password_selfservice();
         },
 
+        on_configuration: function() {
+            var dialog = IPA.dialog({
+                title: '@i18n:customization.customization',
+                fields: [
+                    {
+                        $type: 'text',
+                        name: 'pagination_size',
+                        label: '@i18n:customization.table_pagination',
+                        validators: ['integer']
+                    }
+                ]
+            });
+
+            dialog.create_button({
+                name: 'save',
+                label: '@i18n:buttons.save',
+                click: function () {
+                    if (!dialog.validate()) {
+                        widget_mod.focus_invalid(dialog);
+                        return;
+                    }
+                    var widget = dialog.get_field('pagination_size').widget;
+                    var new_value = widget.get_value()[0];
+                    config.set('table_page_size', new_value, true);
+                    topic.publish('change-pagination');
+                    dialog.close();
+                }
+            });
+
+            dialog.create_button({
+                name: 'cancel',
+                label: '@i18n:buttons.cancel',
+                click: function () {
+                    dialog.close();
+                }
+            });
+
+            dialog.open();
+
+            var size = config.get('table_page_size').toString();
+            dialog.get_field('pagination_size').set_value([size]);
+        },
+
         on_about: function() {
             var dialog = IPA.about_dialog();
             dialog.open();
diff --git a/install/ui/src/freeipa/facet.js b/install/ui/src/freeipa/facet.js
index 4553c5c65e6c334ed451e9c2f1a89ddc455d71c3..414adfd0c329ed6f8929d04b90ee1da814ab3c5f 100644
--- a/install/ui/src/freeipa/facet.js
+++ b/install/ui/src/freeipa/facet.js
@@ -25,12 +25,14 @@ define([
         'dojo/_base/declare',
         'dojo/_base/lang',
         'dojo/dom-construct',
+        'dojo/topic',
         'dojo/on',
         'dojo/Stateful',
         'dojo/Evented',
         './_base/Singleton_registry',
         './_base/construct',
         './builder',
+        './config',
         './ipa',
         './jquery',
         './navigation',
@@ -43,8 +45,8 @@ define([
         './dialog',
         './field',
         './widget'
-       ], function(declare, lang, construct, on, Stateful, Evented,
-                   Singleton_registry, construct_utils, builder, IPA, $,
+    ], function(declare, lang, construct, topic, on, Stateful, Evented,
+                   Singleton_registry, construct_utils, builder, config, IPA, $,
                    navigation, phases, reg, rpc, su, text, ActionDropdownWidget) {
 
 /**
@@ -2312,6 +2314,14 @@ exp.table_facet = IPA.table_facet = function(spec, no_init) {
             selectable: that.selectable && !that.read_only
         });
 
+        topic.subscribe("change-pagination", function() {
+            that.table.page_length = config.get('table_page_size');
+
+            if (that.is_shown) that.refresh();
+
+            that.set_expired_flag();
+        });
+
         var columns = that.columns.values;
         for (var i=0; i<columns.length; i++) {
             var column = columns[i];
diff --git a/install/ui/src/freeipa/widget.js b/install/ui/src/freeipa/widget.js
index 9151ebac9438e9e674f81bfb1ccfe7a63872b1ae..be81f59c439d60792ece2006ad9afb86116db064 100644
--- a/install/ui/src/freeipa/widget.js
+++ b/install/ui/src/freeipa/widget.js
@@ -3590,7 +3590,7 @@ IPA.column = function (spec) {
  * @param {boolean} [spec.save_values=true]
  * @param {string} [spec.class] css class
  * @param {boolean} [spec.pagination] render pagination
- * @param {number} [spec.page_length=20]
+ * @param {number} [spec.page_length=config.table_page_size]
  * @param {boolean} [spec.multivalued=true]
  * @param {Array} columns columns or columns specs
  * @param {string} [value_attr_name=name]
@@ -3615,7 +3615,7 @@ IPA.table_widget = function (spec) {
     that.pagination = spec.pagination;
     that.current_page = 1;
     that.total_pages = 1;
-    that.page_length = spec.page_length || 20;
+    that.page_length = spec.page_length || config.get('table_page_size');
 
     that.multivalued = spec.multivalued === undefined ? true : spec.multivalued;
 
diff --git a/install/ui/src/freeipa/widgets/App.js b/install/ui/src/freeipa/widgets/App.js
index 21e51a70512bd6d8bbf6074cedc3e9d55cda1131..68b78c7c4be44f5a1f658fed6b6b75d1beda22c5 100644
--- a/install/ui/src/freeipa/widgets/App.js
+++ b/install/ui/src/freeipa/widgets/App.js
@@ -234,6 +234,8 @@ define(['dojo/_base/declare',
                 this.emit('logout-click');
             } else if (item.name == 'password_reset') {
                 this.emit('password-reset-click');
+            } else if (item.name == 'configuration') {
+                this.emit('configuration-click');
             } else if (item.name == 'about') {
                 this.emit('about-click');
             }
@@ -265,6 +267,11 @@ define(['dojo/_base/declare',
                         'class': 'divider'
                     },
                     {
+                        name: 'configuration',
+                        label: 'Customization',
+                        icon: 'fa-gear'
+                    },
+                    {
                         name: 'about',
                         label: 'About',
                         icon: 'fa-question'
diff --git a/install/ui/test/data/ipa_init.json b/install/ui/test/data/ipa_init.json
index 77d6fce4e9ca0cf281d89e09f803d6a1a81c6870..f77ba0dcfb67a3dc768c260686b08e1d204f848d 100644
--- a/install/ui/test/data/ipa_init.json
+++ b/install/ui/test/data/ipa_init.json
@@ -101,6 +101,10 @@
                         "update": "Update",
                         "view": "View"
                     },
+                    "customization": {
+                        "customization": "Customization",
+                        "table_pagination": "Table Pagination Size",
+                    },
                     "details": {
                         "collapse_all": "Collapse All",
                         "expand_all": "Expand All",
diff --git a/ipaserver/plugins/internal.py b/ipaserver/plugins/internal.py
index ff29262180a967b2611db17271a742c5e472a19f..225ecd08c51f51d7806aa9b95800d4f09290a225 100644
--- a/ipaserver/plugins/internal.py
+++ b/ipaserver/plugins/internal.py
@@ -250,6 +250,10 @@ class i18n_messages(Command):
             "update": _("Update"),
             "view": _("View"),
         },
+        "customization": {
+            "customization": _("Customization"),
+            "table_pagination": _("Table Pagination Size"),
+        },
         "details": {
             "collapse_all": _("Collapse All"),
             "expand_all": _("Expand All"),
-- 
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