URL: https://github.com/freeipa/freeipa/pull/300
Author: pvomacka
 Title: #300: WebUI: Add support for custom table pagination size
Action: opened

PR body:
"""
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
"""

To pull the PR as Git branch:
git remote add ghfreeipa https://github.com/freeipa/freeipa
git fetch ghfreeipa pull/300/head:pr300
git checkout pr300
From 609b978137ba0593bbdd87444789fdf3c2838b6e 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 d70a778..97e5559 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
@@ -1669,6 +1702,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);

From 8967ef45cff3cf26b5693aa06f58173df624baba 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 61922d4..3bf017b 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();
+});

From 169da2daeca8c5f6734b915f0499d34739ca09df 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 43d5409..32add5f 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 06eca18..bbe2ce3 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) {
 
 /**
@@ -2359,6 +2361,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 041eaa2..91acb77 100644
--- a/install/ui/src/freeipa/widget.js
+++ b/install/ui/src/freeipa/widget.js
@@ -3591,7 +3591,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]
@@ -3616,7 +3616,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 21e51a7..68b78c7 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 514206a..f17a236 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 6107a14..f33d92d 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"),
-- 
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