← Back to team overview

launchpad-reviewers team mailing list archive

[Merge] lp:~rharding/launchpad/lp_cache_update into lp:launchpad

 

Richard Harding has proposed merging lp:~rharding/launchpad/lp_cache_update into lp:launchpad.

Requested reviews:
  Launchpad code reviewers (launchpad-reviewers)

For more details, see:
https://code.launchpad.net/~rharding/launchpad/lp_cache_update/+merge/124217

= Summary =

Part of adding the privacy banner and the information type choice widgets to
the other parts of Launchpad requires copying a bunch of code.

This restructures the LP.cache data and creates a helper to make it simpler
and more reusable.

The eventual goal is to build on this and make the information type choice
widget more of a event driven widget that others can listen to, but that work
is not in this first step.


== Pre Implementation ==

Talked with Aaron on ideas for simplifying and what data is required.


== Implementation Notes ==

We remove the separate cache data for information type data and the list of
private types. We restructure the information type data to be an object vs a
list so that we can key in on the value and allow for finding data without
looping unless absolutely required.

The method that creates the LP.cache data writes out a new is_private property
that code can use to check if a specific information_type_data is private or
not.

We also add a helper method that will take the new object and generate the
list of data that the choicesource code wants to see.

There's a drive by of trying to s/namespace/ns to help aid in line length,
wrapping, and readability.

-- 
https://code.launchpad.net/~rharding/launchpad/lp_cache_update/+merge/124217
Your team Launchpad code reviewers is requested to review the proposed merge of lp:~rharding/launchpad/lp_cache_update into lp:launchpad.
=== modified file 'lib/lp/app/browser/informationtype.py'
--- lib/lp/app/browser/informationtype.py	2012-07-26 05:56:54 +0000
+++ lib/lp/app/browser/informationtype.py	2012-09-13 18:22:25 +0000
@@ -8,6 +8,7 @@
 
 from lazr.restful.interfaces import IJSONRequestCache
 
+from lp.app.utilities import json_dump_information_types
 from lp.registry.enums import PRIVATE_INFORMATION_TYPES
 
 
@@ -15,13 +16,9 @@
 
     def initialize(self):
         cache = IJSONRequestCache(self.request)
-        cache.objects['information_type_data'] = [
-            {'value': term.name, 'description': term.description,
-            'name': term.title,
-            'description_css_class': 'choice-description'}
-            for term in self.context.getAllowedInformationTypes(self.user)]
-        cache.objects['private_types'] = [
-            type.name for type in PRIVATE_INFORMATION_TYPES]
+        json_dump_information_types(
+            cache,
+            self.context.getAllowedInformationTypes(self.user))
 
     @property
     def information_type(self):

=== modified file 'lib/lp/app/javascript/information_type.js'
--- lib/lp/app/javascript/information_type.js	2012-09-10 13:57:38 +0000
+++ lib/lp/app/javascript/information_type.js	2012-09-13 18:22:25 +0000
@@ -6,7 +6,7 @@
 
 YUI.add('lp.app.information_type', function(Y) {
 
-var namespace = Y.namespace('lp.app.information_type');
+var ns = Y.namespace('lp.app.information_type');
 
 // For testing.
 var skip_animation = false;
@@ -24,7 +24,7 @@
  * @param lp_client
  * @param validate_change
  */
-namespace.save_information_type = function(widget, initial_value, value,
+ns.save_information_type = function(widget, initial_value, value,
                                            lp_client, context,
                                            subscribers_list, validate_change) {
     var error_handler = new Y.lp.client.FormErrorHandler();
@@ -35,16 +35,16 @@
     error_handler.handleError = function(ioId, response) {
         if( response.status === 400
                 && response.statusText === 'Bug Visibility') {
-            namespace._confirm_information_type_change(
+            ns._confirm_information_type_change(
                     widget, initial_value, lp_client, context,
                     subscribers_list);
             return true;
         }
-        var orig_value = namespace.information_type_value_from_key(
+        var orig_value = ns.information_type_value_from_key(
             context.information_type, 'name', 'value');
         widget.set('value', orig_value);
         widget._showFailed();
-        namespace.update_privacy_portlet(orig_value);
+        ns.update_privacy_portlet(orig_value);
         return false;
     };
     var submit_url = document.URL + "/+secrecy";
@@ -78,7 +78,7 @@
                 {
                     result_data = Y.JSON.parse(response.responseText);
                 }
-                namespace.information_type_save_success(
+                ns.information_type_save_success(
                     widget, context, value, subscribers_list, result_data);
                 Y.lp.client.display_notifications(
                     response.getResponseHeader('X-Lazr-Notifications'));
@@ -91,18 +91,16 @@
 
 var get_information_type_banner_text = function(value) {
     var text_template = "This page contains {info_type} information.";
-    var info_type = namespace.information_type_value_from_key(
-            value, 'value', 'name');
+    var info_type = ns.information_type_value_from_key(value, 'value', 'name');
     return Y.Lang.sub(text_template, {'info_type': info_type});
 };
 
-namespace.information_type_save_success = function(widget, context, value,
+ns.information_type_save_success = function(widget, context, value,
                                                    subscribers_list,
                                                    subscribers_data) {
     context.information_type =
-        namespace.information_type_value_from_key(
-                value, 'value', 'name');
-    namespace.update_privacy_banner(value);
+        ns.information_type_value_from_key(value, 'value', 'name');
+    ns.update_privacy_banner(value);
     widget._showSucceeded();
     if (Y.Lang.isObject(subscribers_data)) {
         var subscribers = subscribers_data.subscription_data;
@@ -116,8 +114,8 @@
         }
     }
     if (Y.Lang.isValue(subscribers_list)){
-        var ns = Y.lp.bugs.bugtask_index.portlets.subscription;
-        ns.update_subscription_status(skip_animation);
+        var subscription_ns = Y.lp.bugs.bugtask_index.portlets.subscription;
+        subscription_ns.update_subscription_status(skip_animation);
     }
 };
 
@@ -131,13 +129,13 @@
  * @param lp_client
  * @private
  */
-namespace._confirm_information_type_change = function(widget, initial_value,
+ns._confirm_information_type_change = function(widget, initial_value,
                                                       lp_client, context,
                                                       subscribers_list) {
     var value = widget.get('value');
     var do_save = function() {
-        namespace.update_privacy_portlet(value);
-        namespace.save_information_type(
+        ns.update_privacy_portlet(value);
+        ns.save_information_type(
             widget, initial_value, value, lp_client, context, subscribers_list,
             false);
     };
@@ -145,7 +143,7 @@
     // change while the confirmation dialog is showing.
     var new_value = widget.get('value');
     widget.set('value', initial_value);
-    namespace.update_privacy_portlet(initial_value);
+    ns.update_privacy_portlet(initial_value);
     var confirm_text_template = [
         '<p class="block-sprite large-warning">',
         '    You are about to mark this bug as ',
@@ -156,14 +154,13 @@
         '    <strong>Please confirm you really want to do this.</strong>',
         '</p>'
         ].join('');
-    var title = namespace.information_type_value_from_key(
-            value, 'value', 'name');
+    var title = ns.information_type_value_from_key(value, 'value', 'name');
     var confirm_text = Y.Lang.sub(confirm_text_template,
             {information_type: title});
     var co = new Y.lp.app.confirmationoverlay.ConfirmationOverlay({
         submit_fn: function() {
             widget.set('value', new_value);
-            namespace.update_privacy_portlet(new_value);
+            ns.update_privacy_portlet(new_value);
             do_save();
         },
         form_content: confirm_text,
@@ -173,20 +170,23 @@
     co.show();
 };
 
-namespace.setup_information_type_choice = function(privacy_link, lp_client,
+ns.setup_information_type_choice = function(privacy_link, lp_client,
                                                    context, subscribers_list,
                                                    skip_anim) {
     skip_animation = skip_anim;
-    var initial_value = namespace.information_type_value_from_key(
+    var initial_value = ns.information_type_value_from_key(
         context.information_type, 'name', 'value');
     var information_type_value = Y.one('#information-type');
+    var choice_list = ns.information_type_to_choicesource(
+        LP.cache.information_type_data);
+
     var information_type_edit = new Y.ChoiceSource({
         editicon: privacy_link,
         contentBox: Y.one('#privacy'),
         value_location: information_type_value,
         value: initial_value,
         title: "Change information type",
-        items: LP.cache.information_type_data,
+        items: choice_list,
         backgroundColor: '#FFFF99',
         flashEnabled: false
     });
@@ -194,8 +194,8 @@
     information_type_edit.render();
     information_type_edit.on("save", function(e) {
         var value = information_type_edit.get('value');
-        namespace.update_privacy_portlet(value);
-        namespace.save_information_type(
+        ns.update_privacy_portlet(value);
+        ns.save_information_type(
             information_type_edit, initial_value, value, lp_client, context,
             subscribers_list, true);
     });
@@ -206,22 +206,33 @@
 /**
  * Lookup the information_type property, keyed on the named value.
  *
+ * We might want to find based on the name Public or the value PUBLIC so we
+ * allow for the user to request what cache field to search on.
+ *
  * @param cache_key_value the key value to lookup
  * @param key_property_name the key property name used to access the key value
  * @param value_property_name the value property name
  * @return {*}
  */
-namespace.information_type_value_from_key = function(cache_key_value,
-                                                     key_property_name,
-                                                     value_property_name) {
-    var data = null;
-    Y.Array.some(LP.cache.information_type_data, function(info_type) {
-        if (info_type[key_property_name] === cache_key_value) {
-            data = info_type[value_property_name];
-            return true;
+ns.information_type_value_from_key = function(cache_value,
+                                              cache_field,
+                                              data_field) {
+    var cache = LP.cache.information_type_data;
+    for (var key in cache) {
+        if (cache[key][cache_field] === cache_value) {
+            return cache[key][data_field];
         }
-        return false;
-    });
+    }
+};
+
+
+ns.information_type_to_choicesource = function (cache) {
+    var data = [];
+    for (var key in cache) {
+        data.push(cache[key]);
+    }
+    // We need to order data based on the order attribute.
+    data.sort(function(a, b) { return a.order - b.order; });
     return data;
 };
 
@@ -230,16 +241,15 @@
  *
  * @param value
  */
-namespace.update_privacy_portlet = function(value) {
-    var description = namespace.information_type_value_from_key(
+ns.update_privacy_portlet = function(value) {
+    var description = ns.information_type_value_from_key(
         value, 'value', 'description');
     var desc_node = Y.one('#information-type-description');
     if (Y.Lang.isValue(desc_node)) {
         desc_node.set('text', description);
     }
     var summary = Y.one('#information-type-summary');
-    var private_type =
-            Y.Array.indexOf(LP.cache.private_types, value) >= 0;
+    var private_type = LP.cache.information_type_data[value].is_private;
     if (private_type) {
         summary.replaceClass('public', 'private');
     } else {
@@ -252,11 +262,10 @@
  *
  * @param value
  */
-namespace.update_privacy_banner = function(value) {
+ns.update_privacy_banner = function(value) {
     var body = Y.one('body');
     var privacy_banner = Y.lp.app.banner.privacy.getPrivacyBanner();
-    var private_type =
-            Y.Array.indexOf(LP.cache.private_types, value) >= 0;
+    var private_type = LP.cache.information_type_data[value].is_private;
     if (private_type) {
         body.replaceClass('public', 'private');
         var banner_text = get_information_type_banner_text(value);

=== modified file 'lib/lp/app/javascript/tests/test_information_type.js'
--- lib/lp/app/javascript/tests/test_information_type.js	2012-09-10 21:02:05 +0000
+++ lib/lp/app/javascript/tests/test_information_type.js	2012-09-13 18:22:25 +0000
@@ -22,17 +22,28 @@
                         information_type: 'Public',
                         self_link: '/bug/1'
                     },
-                    private_types: ['PROPRIETARY', 'USERDATA'],
-                    information_type_data: [
-                        {'value': 'PUBLIC', 'name': 'Public',
-                            'description': 'Public Description'},
-                        {'value': 'PUBLICSECURITY', 'name': 'Public Security',
-                            'description': 'Public Security Description'},
-                        {'value': 'PROPRIETARY', 'name': 'Proprietary',
-                            'description': 'Private Description'},
-                        {'value': 'USERDATA', 'name': 'Private',
-                            'description': 'Private Description'}
-                    ]
+                    information_type_data: {
+                        PUBLIC: {
+                            value: 'PUBLIC', name: 'Public',
+                            is_private: false,
+                            description: 'Public Description'
+                        },
+                        PUBLICSECURITY: {
+                            value: 'PUBLICSECURITY', name: 'Public Security',
+                            is_private: false,
+                            description: 'Public Security Description'
+                        },
+                        PROPRIETARY: {
+                            value: 'PROPRIETARY', name: 'Proprietary',
+                            is_private: true,
+                            description: 'Private Description'
+                        },
+                        USERDATA: {
+                            value: 'USERDATA', name: 'Private',
+                            is_private: true,
+                            description: 'Private Description'
+                        }
+                    }
                 }
             };
             this.fixture = Y.one('#fixture');
@@ -145,7 +156,7 @@
             this._unshim_privacy_banner(old_func);
         },
 
-        // Setting a private type hides the privacy banner.
+        // Setting a public type hides the privacy banner.
         test_information_type_save_success_public: function() {
             this.makeWidget();
             var old_func = this._shim_privacy_banner();
@@ -156,7 +167,7 @@
             var summary = Y.one('#information-type-summary');
             summary.replaceClass('public', 'private');
 
-            ns.information_type_save_success(this.widget, 'PUBLIC');
+            ns.information_type_save_success(this.widget, 'PUBLIC', 'PUBLIC');
             var body = Y.one('body');
             Y.Assert.isTrue(body.hasClass('public'));
             Y.Assert.isTrue(flag);

=== modified file 'lib/lp/app/utilities/__init__.py'
--- lib/lp/app/utilities/__init__.py	2011-05-27 19:53:20 +0000
+++ lib/lp/app/utilities/__init__.py	2012-09-13 18:22:25 +0000
@@ -0,0 +1,19 @@
+from lp.registry.enums import PUBLIC_INFORMATION_TYPES
+from lp.registry.enums import InformationType
+
+
+
+def json_dump_information_types(cache, information_types):
+    """Dump a dict of the data in the types requsted."""
+    dump = {}
+    order = list(InformationType.sort_order)
+    for term in information_types:
+        dump[term.name] = {
+            'value': term.name,
+            'description': term.description,
+            'name': term.title,
+            'order': order.index(term.name),
+            'is_private': (term not in PUBLIC_INFORMATION_TYPES), 'description_css_class': 'choice-description',
+        }
+
+    cache.objects['information_type_data'] = dump

=== modified file 'lib/lp/bugs/browser/bugtarget.py'
--- lib/lp/bugs/browser/bugtarget.py	2012-08-21 04:04:47 +0000
+++ lib/lp/bugs/browser/bugtarget.py	2012-09-13 18:22:25 +0000
@@ -69,6 +69,7 @@
     ILaunchpadCelebrities,
     ILaunchpadUsage,
     )
+from lp.app.utilities import json_dump_information_types
 from lp.app.validators.name import valid_name_pattern
 from lp.app.widgets.itemswidgets import LaunchpadRadioWidgetWithDescription
 from lp.app.widgets.product import (
@@ -259,17 +260,13 @@
         # the form is rendered during LaunchpadFormView's initialize()
         # when an action is invokved.
         cache = IJSONRequestCache(self.request)
-        cache.objects['private_types'] = [
-            type.name for type in PRIVATE_INFORMATION_TYPES]
         cache.objects['bug_private_by_default'] = (
             self.context.pillar.getDefaultBugInformationType() in
             PRIVATE_INFORMATION_TYPES)
-        cache.objects['information_type_data'] = [
-            {'value': term.name, 'description': term.description,
-            'name': term.title,
-            'description_css_class': 'choice-description'}
-            for term in
-            self.context.pillar.getAllowedBugInformationTypes()]
+        json_dump_information_types(
+            cache,
+            self.context.pillar.getAllowedBugInformationTypes())
+
         bugtask_status_data = vocabulary_to_choice_edit_items(
             BugTaskStatus, include_description=True, css_class_prefix='status',
             excluded_items=[

=== modified file 'lib/lp/bugs/browser/tests/test_bugtarget_filebug.py'
--- lib/lp/bugs/browser/tests/test_bugtarget_filebug.py	2012-08-29 03:19:38 +0000
+++ lib/lp/bugs/browser/tests/test_bugtarget_filebug.py	2012-09-13 18:22:25 +0000
@@ -28,6 +28,7 @@
     BugSharingPolicy,
     InformationType,
     PRIVATE_INFORMATION_TYPES,
+    PUBLIC_INFORMATION_TYPES,
     )
 from lp.registry.interfaces.projectgroup import IProjectGroup
 from lp.services.webapp.servers import LaunchpadTestRequest
@@ -636,16 +637,15 @@
             bugtask_importance_data.append(new_item)
         self.assertEqual(
             bugtask_importance_data, cache['bugtask_importance_data'])
-        self.assertContentEqual(cache['private_types'], [
-            type.name for type in PRIVATE_INFORMATION_TYPES])
         self.assertEqual(cache['bug_private_by_default'], private_bugs)
-        bugtask_info_type_data = []
+        bugtask_info_type_data = {}
         if not IProjectGroup.providedBy(view.context):
             for item in view.context.getAllowedBugInformationTypes():
                 new_item = {'name': item.title, 'value': item.name,
                             'description': item.description,
+                            'is_private': item not in PUBLIC_INFORMATION_TYPES,
                             'description_css_class': 'choice-description'}
-                bugtask_info_type_data.append(new_item)
+                bugtask_info_type_data[item.name] = new_item
             self.assertContentEqual(
                 bugtask_info_type_data, cache['information_type_data'])
 

=== modified file 'lib/lp/bugs/browser/tests/test_bugview.py'
--- lib/lp/bugs/browser/tests/test_bugview.py	2012-08-08 05:43:18 +0000
+++ lib/lp/bugs/browser/tests/test_bugview.py	2012-09-13 18:22:25 +0000
@@ -104,4 +104,4 @@
             InformationType.USERDATA.name]
         self.assertContentEqual(expected, [
             type['value']
-            for type in cache.objects['information_type_data']])
+            for type in cache.objects['information_type_data'].values()])

=== modified file 'lib/lp/bugs/javascript/filebug.js'
--- lib/lp/bugs/javascript/filebug.js	2012-09-05 23:06:42 +0000
+++ lib/lp/bugs/javascript/filebug.js	2012-09-13 18:22:25 +0000
@@ -42,9 +42,9 @@
         val = itypes_table.one(
             "input[name='field.information_type']:checked").get('value');
     } else {
-        val = 'PUBLIC'; 
+        val = 'PUBLIC';
     }
-    
+
     if (LP.cache.bug_private_by_default) {
         var filebug_privacy_text = "This report will be private. " +
             "You can disclose it later.";
@@ -65,20 +65,17 @@
 };
 
 var get_new_banner_text = function(value) {
-    var info_type_descriptions = {};
-    Y.Array.forEach(LP.cache.information_type_data, function(item) {
-        info_type_descriptions[item.value] = item.name;
-    });
+    var cache = LP.cache.information_type_data;
     var text_template = "This report contains {info_type} information." +
         " You can change the information type later.";
-    value = info_type_descriptions[value];
-    return Y.Lang.substitute(text_template, {'info_type': value});
+    return Y.Lang.substitute(text_template, {
+        'info_type': cache[value].name
+    });
 };
 
 var update_banner_from_information_type = function(value) {
     var banner_text = get_new_banner_text(value);
-    var is_private = (Y.Array.indexOf(
-        LP.cache.private_types, value) >= 0);
+    var is_private = LP.cache.information_type_data[value].is_private;
     update_privacy_banner(is_private, banner_text);
 };
 
@@ -94,12 +91,17 @@
     }, "input[name='field.information_type']");
 };
 
+
 var setupChoiceWidgets = function() {
     Y.lp.app.choice.addPopupChoice('status', LP.cache.bugtask_status_data);
     Y.lp.app.choice.addPopupChoice(
         'importance', LP.cache.bugtask_importance_data);
+    var cache = LP.cache.information_type_data;
+    var information_helpers = Y.lp.app.information_type
+    var choices = information_helpers.information_type_to_choicesource(cache)
+
     Y.lp.app.choice.addPopupChoiceForRadioButtons(
-        'information_type', LP.cache.information_type_data, true);
+        'information_type', choices, true);
 };
 
 var setup_security_related = function() {
@@ -125,5 +127,5 @@
 
 }, "0.1", {"requires": [
     "base", "node", "event", "node-event-delegate", "lp.ui.choiceedit",
-    "lp.app.banner.privacy", "lp.app.choice",
+    "lp.app.banner.privacy", "lp.app.choice", "lp.app.information_type",
     "lp.bugs.filebug_dupefinder"]});

=== modified file 'lib/lp/bugs/javascript/tests/test_buglisting.html'
--- lib/lp/bugs/javascript/tests/test_buglisting.html	2012-06-27 19:49:35 +0000
+++ lib/lp/bugs/javascript/tests/test_buglisting.html	2012-09-13 18:22:25 +0000
@@ -34,6 +34,8 @@
       <script type="text/javascript"
           src="../../../../../build/js/lp/app/client.js"></script>
       <script type="text/javascript"
+          src="../../../../../build/js/lp/app/configutils.js"></script>
+      <script type="text/javascript"
           src="../../../../../build/js/lp/app/errors.js"></script>
       <script type="text/javascript"
           src="../../../../../build/js/lp/app/expander.js"></script>
@@ -50,6 +52,8 @@
       <script type="text/javascript"
           src="../../../../../build/js/lp/app/inlinehelp/inlinehelp.js"></script>
       <script type="text/javascript"
+          src="../../../../../build/js/lp/bugs/buglisting_utils.js"></script>
+      <script type="text/javascript"
           src="../../../../../build/js/lp/app/overlay/overlay.js"></script>
       <script type="text/javascript"
           src="../../../../../build/js/lp/app/testing/assert.js"></script>

=== modified file 'lib/lp/bugs/javascript/tests/test_filebug.html'
--- lib/lp/bugs/javascript/tests/test_filebug.html	2012-07-17 14:13:55 +0000
+++ lib/lp/bugs/javascript/tests/test_filebug.html	2012-09-13 18:22:25 +0000
@@ -40,6 +40,9 @@
       <script type="text/javascript"
           src="../../../../../build/js/lp/app/formwidgets/resizing_textarea.js"></script>
       <script type="text/javascript"
+          src="../../../../../build/js/lp/app/information_type.js"></script>
+
+      <script type="text/javascript"
           src="../../../../../build/js/lp/app/overlay/overlay.js"></script>
       <script type="text/javascript"
           src="../../../../../build/js/lp/app/anim/anim.js"></script>

=== modified file 'lib/lp/bugs/javascript/tests/test_filebug.js'
--- lib/lp/bugs/javascript/tests/test_filebug.js	2012-08-27 00:38:02 +0000
+++ lib/lp/bugs/javascript/tests/test_filebug.js	2012-09-13 18:22:25 +0000
@@ -13,16 +13,21 @@
             window.LP = {
                 links: {},
                 cache: {
-                    private_types: ['PRIVATESECURITY', 'USERDATA'],
-                    information_type_data: [
-                        {name: 'Public', value: 'PUBLIC',
+                    information_type_data: {
+                        PUBLIC: {
+                            name: 'Public', value: 'PUBLIC',
+                            is_private: false,
                             description: 'Public bug'},
-                        {name: 'Private Security',
+                        PRIVATESECURITY: {
+                            name: 'Private Security',
                             value: 'PRIVATESECURITY',
+                            is_private: true,
                             description: 'private security bug'},
-                        {name: 'Private', value: 'USERDATA',
+                        USERDATA: {
+                            name: 'Private', value: 'USERDATA',
+                            is_private: true,
                             description: 'Private bug'}
-                    ],
+                    },
                     bugtask_status_data: [
                         {name: 'New', value: 'New'},
                         {name: 'Incomplete', value: 'Incomplete'}

=== modified file 'lib/lp/code/javascript/branch.information_type_choice.js'
--- lib/lp/code/javascript/branch.information_type_choice.js	2012-09-10 15:23:33 +0000
+++ lib/lp/code/javascript/branch.information_type_choice.js	2012-09-13 18:22:25 +0000
@@ -31,7 +31,9 @@
             value_location: information_type_value,
             value: initial_value,
             title: "Change information type",
-            items: LP.cache.information_type_data,
+            items: information_type.information_type_to_choicesource(
+                LP.cache.information_type_data
+            ),
             backgroundColor: '#FFFF99',
             flashEnabled: false
         });

=== modified file 'lib/lp/code/javascript/tests/test_information_type_choice.js'
--- lib/lp/code/javascript/tests/test_information_type_choice.js	2012-09-10 21:02:05 +0000
+++ lib/lp/code/javascript/tests/test_information_type_choice.js	2012-09-13 18:22:25 +0000
@@ -17,17 +17,25 @@
                         web_link: '',
                         information_type: 'Public'
                     },
-                    private_types: ['PROPRIETARY', 'USERDATA'],
-                    information_type_data: [
-                        {'value': 'PUBLIC', 'name': 'Public',
-                            'description': 'Public Description'},
-                        {'value': 'PUBLICSECURITY', 'name': 'Public Security',
-                            'description': 'Public Security Description'},
-                        {'value': 'PROPRIETARY', 'name': 'Proprietary',
-                            'description': 'Private Description'},
-                        {'value': 'USERDATA', 'name': 'Private',
-                            'description': 'Private Description'}
-                    ]
+                    information_type_data: {
+                        PUBLIC: {
+                            value: 'PUBLIC', name: 'Public',
+                            is_private: false,
+                            description: 'Public Description'
+                        },
+                        PUBLICSECURITY: {
+                            value: 'PUBLICSECURITY', name: 'Public Security',
+                            is_private: false,
+                            description: 'Public Security Description'},
+                        PROPRIETARY: {
+                            value: 'PROPRIETARY', name: 'Proprietary',
+                            is_private: true,
+                            description: 'Private Description'},
+                        USERDATA: {
+                            value: 'USERDATA', name: 'Private',
+                            is_private: true,
+                            description: 'Private Description'}
+                    }
                 }
             };
             this.fixture = Y.one('#fixture');

=== modified file 'lib/lp/registry/browser/product.py'
--- lib/lp/registry/browser/product.py	2012-09-12 11:55:21 +0000
+++ lib/lp/registry/browser/product.py	2012-09-13 18:22:25 +0000
@@ -112,6 +112,7 @@
 from lp.app.errors import NotFoundError
 from lp.app.interfaces.headings import IEditableContextTitle
 from lp.app.interfaces.launchpad import ILaunchpadCelebrities
+from lp.app.utilities import json_dump_information_types
 from lp.app.widgets.date import DateWidget
 from lp.app.widgets.itemswidgets import (
     CheckBoxMatrixWidget,
@@ -158,11 +159,7 @@
     PillarViewMixin,
     )
 from lp.registry.browser.productseries import get_series_branch_error
-from lp.registry.enums import (
-    InformationType,
-    PRIVATE_INFORMATION_TYPES,
-    PUBLIC_INFORMATION_TYPES,
-    )
+from lp.registry.enums import InformationType
 from lp.registry.interfaces.pillar import IPillarNameSet
 from lp.registry.interfaces.product import (
     IProduct,
@@ -2031,17 +2028,9 @@
         # when an action is invokved.
         if IProductSet.providedBy(self.context):
             cache = IJSONRequestCache(self.request)
-            cache.objects['private_types'] = [
-                type.name for type in PRIVATE_INFORMATION_TYPES]
-            cache.objects['public_types'] = [
-                    type.name for type in PUBLIC_INFORMATION_TYPES]
-            cache.objects['information_type_data'] = [
-                {'value': term.name, 'description': term.description,
-                'name': term.title,
-                'description_css_class': 'choice-description'}
-                for term in
-                    self.context.getAllowedProductInformationTypes()]
-
+            json_dump_information_types(
+                cache,
+                self.context.getAllowedProductInformationTypes())
         super(ProjectAddStepTwo, self).initialize()
 
     @property


Follow ups