~launchpad-pqm/launchpad/devel

14241.3.6 by Deryck Hodge
Add basic BugListingConfigUtil object and link to dependency from
1
/* Copyright (c) 2011, Canonical Ltd. All rights reserved. */
2
3
YUI().add('lp.buglisting_utils', function(Y) {
4
    /**
14333.1.19 by Aaron Bentley
Fake merge of devel into history-model.
5
     * A utility for configuring the display of bug listings.
14241.3.45 by Deryck Hodge
Add comments and use constants.
6
     *
7
     * The purpose of this widget is be a mechanism for turning
8
     * fields on and off in a bug listing display.  It extends
9
     * from BaseConfigUtil, which provides the clickable settings
10
     * icon.  When the icon is clicked, a form overlay opens with
11
     * various checkboxes for turning fields on and off.
12
     *
13
     * This doesn't actually change the display, though.  It fires
14
     * an event that the buglisting navigator will hook into to update
15
     * the list's display.
14241.3.6 by Deryck Hodge
Add basic BugListingConfigUtil object and link to dependency from
16
     *
17
     * @module lp.buglisting_utils
18
     */
14241.3.45 by Deryck Hodge
Add comments and use constants.
19
20
    // Constants.
14333.1.19 by Aaron Bentley
Fake merge of devel into history-model.
21
    var FORM = 'form';
22
14333.1.4 by Aaron Bentley
Extract BugListingModel from BugListingConfigUtil
23
14241.3.45 by Deryck Hodge
Add comments and use constants.
24
    /**
25
     * BugListingConfigUtil is the main object used to manipulate
26
     * a bug listing's display.
27
     *
14333.1.19 by Aaron Bentley
Fake merge of devel into history-model.
28
     * Constructor accepts a config containing
29
     * - model (a BugListingModel)
30
     * - cookie_name
31
     * - form the FormOverlay to manipulate
32
     *
33
     * If model is not supplied, model parameters must be included, especially
34
     * - form_visibility
35
     * - form_visibility_defaults
36
     *
14241.3.45 by Deryck Hodge
Add comments and use constants.
37
     * @class BugListingConfigUtil
38
     * @extends Y.lp.configutils.BaseConfigUtil
39
     * @constructor
40
     */
14241.3.6 by Deryck Hodge
Add basic BugListingConfigUtil object and link to dependency from
41
    function BugListingConfigUtil() {
42
        BugListingConfigUtil.superclass.constructor.apply(this, arguments);
43
    }
44
14241.3.31 by Deryck Hodge
Add test for event handling. Update NAME to be more readable.
45
    BugListingConfigUtil.NAME = 'buglisting-config-util';
14241.3.6 by Deryck Hodge
Add basic BugListingConfigUtil object and link to dependency from
46
14241.3.13 by Deryck Hodge
Get merge of user supplied field_visibility with defaults working.
47
    /**
14241.3.24 by Deryck Hodge
Bit of refactoring to correctly handle reference objects.
48
     * Object to reference display names for field_visibility
49
     * form inputs.
50
     */
14241.3.46 by Deryck Hodge
Bunch of renames for readability.
51
    BugListingConfigUtil.field_display_names = {
14543.1.1 by Rick harding
Update names to remove the 'bug' where not required
52
        show_id: 'Number',
14241.3.19 by Deryck Hodge
Get the form rendering.
53
        show_importance: 'Importance',
54
        show_status: 'Status',
14543.1.1 by Rick harding
Update names to remove the 'bug' where not required
55
        show_heat: 'Heat',
14333.2.9 by Abel Deuring
s/show_bugtarget/show_targetname/
56
        show_targetname: 'Package/Project/Series name',
14543.1.1 by Rick harding
Update names to remove the 'bug' where not required
57
        show_datecreated: 'Age',
58
        show_date_last_updated: 'Date last updated',
14241.3.57 by Deryck Hodge
Update defaults for listings display.
59
        show_assignee: 'Assignee',
14241.3.61 by Deryck Hodge
Text changes to better match mockup. Minor CSS updates as a result.
60
        show_reporter: 'Reporter',
14241.3.57 by Deryck Hodge
Update defaults for listings display.
61
        show_milestone_name: 'Milestone',
14543.1.1 by Rick harding
Update names to remove the 'bug' where not required
62
        show_tag: 'Tags'
14241.3.19 by Deryck Hodge
Get the form rendering.
63
    };
64
14241.3.6 by Deryck Hodge
Add basic BugListingConfigUtil object and link to dependency from
65
    BugListingConfigUtil.ATTRS = {
66
67
        /**
14317.1.29 by Deryck Hodge
Get cookie_name from the cache in js code.
68
         * The cookie name as set by the view.
69
         *
70
         * We get this value from the LP cache.
71
         *
72
         * @attribute cookie_name
73
         * @type String
74
         */
75
        cookie_name: {
76
            valueFn: function() {
77
                if (
78
                    Y.Lang.isValue(window.LP) &&
79
                    Y.Lang.isValue(LP.cache.cbl_cookie_name)) {
80
                    return LP.cache.cbl_cookie_name;
81
                } else {
82
                    return '';
83
                }
84
            }
85
        },
86
87
        /**
14241.3.17 by Deryck Hodge
Add form attribute.
88
         * A reference to the form overlay used in the overlay.
89
         *
90
         * @attribute form
91
         * @type Y.lazr.FormOverlay
92
         * @default null
93
         */
94
        form: {
95
            value: null
14333.1.19 by Aaron Bentley
Fake merge of devel into history-model.
96
        },
97
        model: {
98
            value: null
14333.1.7 by Aaron Bentley
Remove LP.cache fallbacks.
99
        }
14241.3.6 by Deryck Hodge
Add basic BugListingConfigUtil object and link to dependency from
100
    };
101
14241.3.19 by Deryck Hodge
Get the form rendering.
102
    BugListingConfigUtil.INPUT_TEMPLATE = [
14436.3.1 by Huw Wilkins
Bug listing config options now use a list and labels.
103
        '<li><input type="checkbox" class="{name}" name="{name}" ',
14436.3.2 by Huw Wilkins
Added suffix to ids to hopefully make them a little more unique
104
        'value="{display_name}" id="{name}_id" {checked}> ',
105
        '<label for="{name}_id">{display_name}</label></li>'].join('');
14241.3.19 by Deryck Hodge
Get the form rendering.
106
107
    Y.extend(BugListingConfigUtil, Y.lp.configutils.BaseConfigUtil, {
108
14333.1.19 by Aaron Bentley
Fake merge of devel into history-model.
109
        initializer: function(config){
110
            if (config === undefined){
111
                config = {};
112
            }
113
            if (Y.Lang.isNull(this.get('model'))){
114
                this.set('model',
115
                    new Y.lp.bugs.buglisting.BugListingModel(config));
116
            }
117
        },
118
14241.3.23 by Deryck Hodge
Add comments and destructor to cleanup form overlay.
119
        /**
120
         * Hook into the destroy lifecyle to ensure the form
121
         * overlay is destroyed.
122
         *
123
         * @method destructor
124
         */
125
        destructor: function() {
14241.3.45 by Deryck Hodge
Add comments and use constants.
126
            if (Y.Lang.isValue(this.get(FORM))) {
127
                var form = this.get(FORM);
128
                this.set(FORM, null);
14241.3.23 by Deryck Hodge
Add comments and destructor to cleanup form overlay.
129
                form.destroy();
130
            }
131
        },
132
133
        /**
134
         * Build the input nodes used on the form overlay.
135
         *
14241.3.46 by Deryck Hodge
Bunch of renames for readability.
136
         * @method getFormInputs
14241.3.23 by Deryck Hodge
Add comments and destructor to cleanup form overlay.
137
         */
14241.3.46 by Deryck Hodge
Bunch of renames for readability.
138
        getFormInputs: function() {
14333.1.19 by Aaron Bentley
Fake merge of devel into history-model.
139
            var fields = this.get('model').get_field_visibility();
14241.3.46 by Deryck Hodge
Bunch of renames for readability.
140
            var display_names = this.constructor.field_display_names;
14241.3.37 by Deryck Hodge
Build a reset link to get final test passing.
141
            var nodes = [];
14241.3.49 by Deryck Hodge
Clean lint.
142
            var item,
143
                name,
14241.3.19 by Deryck Hodge
Get the form rendering.
144
                display_name,
14241.3.21 by Deryck Hodge
Handle checked attribute correctly.
145
                checked,
14241.3.19 by Deryck Hodge
Get the form rendering.
146
                input_html,
147
                input_node;
148
            for (item in fields) {
149
                if (fields.hasOwnProperty(item)) {
150
                    name = item;
14241.3.24 by Deryck Hodge
Bit of refactoring to correctly handle reference objects.
151
                    display_name = display_names[item];
14241.3.19 by Deryck Hodge
Get the form rendering.
152
                    if (fields[item] === true) {
153
                        checked = 'checked';
14241.3.21 by Deryck Hodge
Handle checked attribute correctly.
154
                    } else {
155
                        checked = '';
14241.3.19 by Deryck Hodge
Get the form rendering.
156
                    }
14241.3.49 by Deryck Hodge
Clean lint.
157
                    input_html = Y.Lang.substitute(
158
                        this.constructor.INPUT_TEMPLATE,
159
                        {name: name, display_name: display_name,
160
                        checked: checked});
161
                    input_node = Y.Node.create(input_html);
162
                    nodes.push(input_node);
14241.3.19 by Deryck Hodge
Get the form rendering.
163
                }
164
            }
14241.3.37 by Deryck Hodge
Build a reset link to get final test passing.
165
            return new Y.NodeList(nodes);
166
        },
167
168
        /**
169
         * Build the reset link for the form.
170
         *
171
         * Also, provide a click handler to reset the fields config.
172
         *
14241.3.46 by Deryck Hodge
Bunch of renames for readability.
173
         * @method getResetLink
14241.3.37 by Deryck Hodge
Build a reset link to get final test passing.
174
         */
14241.3.46 by Deryck Hodge
Bunch of renames for readability.
175
        getResetLink: function() {
14241.3.37 by Deryck Hodge
Build a reset link to get final test passing.
176
            var link = Y.Node.create('<a></a>');
177
            link.addClass('js-action');
178
            link.addClass('reset-buglisting');
179
            link.setContent('Reset to default');
180
            link.on('click', function(e) {
14333.1.19 by Aaron Bentley
Fake merge of devel into history-model.
181
                var model = this.get('model');
182
                var defaults = model.get('field_visibility_defaults');
14241.3.89 by Deryck Hodge
Refactor field set and form hide into helper method.
183
                this.updateFieldVisibilty(defaults, true);
14317.1.13 by Deryck Hodge
Remove cookie and update test to check for empty string.
184
                this.setCookie();
14241.3.37 by Deryck Hodge
Build a reset link to get final test passing.
185
            }, this);
186
            return link;
14241.3.19 by Deryck Hodge
Get the form rendering.
187
        },
188
14241.3.23 by Deryck Hodge
Add comments and destructor to cleanup form overlay.
189
        /**
14241.3.36 by Deryck Hodge
Begin refactoring form content building.
190
         * Build the form content for form overlay.
191
         *
14241.3.46 by Deryck Hodge
Bunch of renames for readability.
192
         * @method buildFormContent
14241.3.36 by Deryck Hodge
Begin refactoring form content building.
193
         */
14241.3.46 by Deryck Hodge
Bunch of renames for readability.
194
        buildFormContent: function() {
14241.3.37 by Deryck Hodge
Build a reset link to get final test passing.
195
            var div = Y.Node.create(
14436.3.1 by Huw Wilkins
Bug listing config options now use a list and labels.
196
                '<ul></ul>').addClass('buglisting-opts');
14241.3.46 by Deryck Hodge
Bunch of renames for readability.
197
            var inputs = this.getFormInputs();
14241.3.37 by Deryck Hodge
Build a reset link to get final test passing.
198
            div.append(inputs);
14241.3.46 by Deryck Hodge
Bunch of renames for readability.
199
            var link = this.getResetLink();
14241.3.37 by Deryck Hodge
Build a reset link to get final test passing.
200
            div.append(link);
201
            return div;
14241.3.36 by Deryck Hodge
Begin refactoring form content building.
202
        },
203
204
        /**
14241.3.91 by Deryck Hodge
Add a comment.
205
         * Helper method for updating field_visibility.
206
         *
207
         * @method updateFieldVisibilty
208
         */
14241.3.89 by Deryck Hodge
Refactor field set and form hide into helper method.
209
        updateFieldVisibilty: function(fields, destroy_form) {
14333.1.19 by Aaron Bentley
Fake merge of devel into history-model.
210
            this.get('model').set_field_visibility(fields);
14317.1.4 by Deryck Hodge
Get setting fields from cookie values working.
211
            var form = this.get(FORM);
212
            if (Y.Lang.isValue(form)) {
213
                form.hide();
214
            }
14241.3.89 by Deryck Hodge
Refactor field set and form hide into helper method.
215
            // Destroy the form and rebuild it.
216
            if (destroy_form === true) {
217
                this.get(FORM).hide();
218
                this._extraRenderUI();
219
            }
220
        },
221
14241.3.33 by Deryck Hodge
Factor out event firing to its own method.
222
        /**
14241.3.30 by Deryck Hodge
Update field_visibility config when the form is submitted.
223
         * Process the data from the form overlay submit.
224
         *
225
         * data is an object whose members are the checked
226
         * input elements from the form.  data has the same members
227
         * as field_visibility, so if the key is in data it should
228
         * be set to true in field_visibility.
229
         *
14241.3.46 by Deryck Hodge
Bunch of renames for readability.
230
         * @method handleOverlaySubmit
14241.3.30 by Deryck Hodge
Update field_visibility config when the form is submitted.
231
         */
14241.3.46 by Deryck Hodge
Bunch of renames for readability.
232
        handleOverlaySubmit: function(data) {
14333.1.19 by Aaron Bentley
Fake merge of devel into history-model.
233
            var fields = this.get('model').get_field_visibility();
14241.3.49 by Deryck Hodge
Clean lint.
234
            var member;
14241.3.30 by Deryck Hodge
Update field_visibility config when the form is submitted.
235
            for (member in fields) {
236
                if (fields.hasOwnProperty(member)) {
237
                    if (Y.Lang.isValue(data[member])) {
238
                        // If this field exists in data, set it true.
239
                        // in field_visibility.
240
                        fields[member] = true;
241
                    } else {
242
                        // Otherwise, set the member to false in
243
                        // field_visibility.
244
                        fields[member] = false;
245
                    }
246
                }
247
            }
14241.3.89 by Deryck Hodge
Refactor field set and form hide into helper method.
248
            this.updateFieldVisibilty(fields);
14317.1.8 by Deryck Hodge
Set the cookie on update of form.
249
            this.setCookie(fields);
14241.3.30 by Deryck Hodge
Update field_visibility config when the form is submitted.
250
        },
251
14317.1.6 by Deryck Hodge
Add comments.
252
        /**
14317.1.8 by Deryck Hodge
Set the cookie on update of form.
253
         * Set the given value for the buglisting config cookie.
254
         * If config is not specified, the cookie will be cleared.
255
         *
256
         * @method setCookie
257
         */
258
        setCookie: function(config) {
14317.1.29 by Deryck Hodge
Get cookie_name from the cache in js code.
259
            var cookie_name = this.get('cookie_name');
14317.1.8 by Deryck Hodge
Set the cookie on update of form.
260
            if (Y.Lang.isValue(config)) {
14317.1.20 by Deryck Hodge
Set path and expires for cookie.
261
                Y.Cookie.setSubs(cookie_name, config, {
262
                    path: '/',
263
                    expires: new Date('January 19, 2038')});
14317.1.8 by Deryck Hodge
Set the cookie on update of form.
264
            } else {
14448.3.1 by Aaron Bentley
Fix form reset functionality.
265
                Y.Cookie.remove(cookie_name, {path: '/'});
14317.1.8 by Deryck Hodge
Set the cookie on update of form.
266
            }
267
        },
268
269
        /**
14241.3.23 by Deryck Hodge
Add comments and destructor to cleanup form overlay.
270
         * Hook in _extraRenderUI provided by BaseConfigUtil
271
         * to add a form overlay to the widget.
272
         *
273
         * @method _extraRenderUI
274
         */
14241.3.19 by Deryck Hodge
Get the form rendering.
275
        _extraRenderUI: function() {
14241.3.46 by Deryck Hodge
Bunch of renames for readability.
276
            var form_content = this.buildFormContent();
277
            var on_submit_callback = Y.bind(this.handleOverlaySubmit, this);
14241.3.19 by Deryck Hodge
Get the form rendering.
278
            util_overlay = new Y.lazr.FormOverlay({
279
                align: 'left',
14241.3.61 by Deryck Hodge
Text changes to better match mockup. Minor CSS updates as a result.
280
                headerContent: '<h2>Visible information</h2>',
14241.3.19 by Deryck Hodge
Get the form rendering.
281
                centered: true,
14241.3.36 by Deryck Hodge
Begin refactoring form content building.
282
                form_content: form_content,
14241.3.19 by Deryck Hodge
Get the form rendering.
283
                form_submit_button: Y.Node.create(
284
                    '<input type="submit" value="Update" ' +
285
                    'class="update-buglisting" />'
286
                ),
287
                form_cancel_button: Y.Node.create(
288
                    '<button type="button" name="field.actions.cancel" ' +
14241.3.56 by Deryck Hodge
Style rules for config util overlay.
289
                    'class="hidden" >Cancel</button>'
14241.3.19 by Deryck Hodge
Get the form rendering.
290
                ),
14241.3.30 by Deryck Hodge
Update field_visibility config when the form is submitted.
291
                form_submit_callback: on_submit_callback
14241.3.19 by Deryck Hodge
Get the form rendering.
292
            });
14241.3.56 by Deryck Hodge
Style rules for config util overlay.
293
            util_overlay.get(
294
                'boundingBox').addClass(this.getClassName('overlay'));
14241.3.45 by Deryck Hodge
Add comments and use constants.
295
            this.set(FORM, util_overlay);
14241.3.19 by Deryck Hodge
Get the form rendering.
296
            util_overlay.render();
297
            util_overlay.hide();
14241.3.28 by Deryck Hodge
Get test passing by showing the overlay on click.
298
        },
299
300
        /**
301
         * Hook into _handleClick provided by BaseConfigUtil
302
         * to show overlay when the settings cog icon is clicked.
303
         *
304
         * @method _handleClick
305
         */
306
        _handleClick: function() {
14241.3.45 by Deryck Hodge
Add comments and use constants.
307
            var form = this.get(FORM);
14241.3.28 by Deryck Hodge
Get test passing by showing the overlay on click.
308
            form.show();
14241.3.19 by Deryck Hodge
Get the form rendering.
309
        }
14241.3.28 by Deryck Hodge
Get test passing by showing the overlay on click.
310
14241.3.19 by Deryck Hodge
Get the form rendering.
311
    });
14241.3.6 by Deryck Hodge
Add basic BugListingConfigUtil object and link to dependency from
312
313
    var buglisting_utils = Y.namespace('lp.buglisting_utils');
314
    buglisting_utils.BugListingConfigUtil = BugListingConfigUtil;
315
14333.2.4 by Abel Deuring
new function Y.lp.buglisting_utils.update_sort_button_visibility()
316
    /**
317
     * Update the visibilty of the sort buttons.
318
     *
319
     * We want to display only the sort buttons for fields which
320
     * are displayed. To avoid surprises for users, the current sort
321
     * order is always displayed, even when the related data is not
322
     * shown.
323
     *
324
     * @param orderbybar {Object} The order by bar.
325
     * @param data_visibility {Associative Array} The visibility data
326
     *     as used in Y.bugs.buglisting.BugListingModel.
327
     */
328
    function update_sort_button_visibility(orderbybar, data_visibility) {
329
        // We must translate the field names as used by
330
        // BugListingConfigUtil to those used by the "order by" buttons.
331
        var orderby_visibility = {};
14333.2.12 by Abel Deuring
remove obsolete display_to_orderby mapping from update_sort_button_visibility()
332
        var order_key;
333
        var data_key;
334
        for (data_key in data_visibility) {
335
            if (data_visibility.hasOwnProperty(data_key) &&
336
                data_key.substring(0, 5) === 'show_') {
337
                order_key = data_key.replace('show_', '');
338
                orderby_visibility[order_key] = data_visibility[data_key];
339
            }
14333.2.4 by Abel Deuring
new function Y.lp.buglisting_utils.update_sort_button_visibility()
340
        }
14487.4.1 by Abel Deuring
add JS sort buttons for sort orders implemented by BugTaskSet.search()
341
        // Never hide the button for the current sort order...
14333.2.4 by Abel Deuring
new function Y.lp.buglisting_utils.update_sort_button_visibility()
342
        orderby_visibility[orderbybar.get('active')] = true;
14487.4.4 by Abel Deuring
reorder the buglisting sort buttons to match the order of the displayed data; always show the 'sort by title' button in bug listings
343
        // ...and buttons for sort orders that should always be displayed.
344
        Y.each(orderbybar.always_display, function(sort_key) {
345
            orderby_visibility[sort_key] = true;
346
        });
14333.2.4 by Abel Deuring
new function Y.lp.buglisting_utils.update_sort_button_visibility()
347
        orderbybar.updateVisibility(orderby_visibility);
348
    }
349
350
    buglisting_utils.update_sort_button_visibility =
351
        update_sort_button_visibility;
352
14333.1.19 by Aaron Bentley
Fake merge of devel into history-model.
353
}, '0.1', {'requires': [
354
    'cookie', 'history', 'lp.configutils', 'lazr.formoverlay',
355
    'lp.bugs.buglisting'
356
    ]});