Interface for adding/removing widgets

Review Request #5622 — Created March 14, 2014 and submitted

Information

Review Board
master

Reviewers

Users can add widgets to their admin dashboard by clicking on "Add Widgets," which will open a modal displaying a list of widgets that they can choose from.

They can remove widgets by clicking the X icon on the upper righthand corner of the widget in question.

Removed widgets and added them back to make sure that newly added widgets appeared below the old widgets.


Description From Last Updated

This could be a bit more efficient. You can either do a single for p in primary_widgets and then append …

daviddavid

Same here about iterating over the list twice.

daviddavid

If several widgets don't have given positions, won't this result in several of the values in positions being set to …

daviddavid

Add a space between the # and the comment.

daviddavid

Can you combine these two into one rule? #all-primary-widgets, #all-secondary-widgets { display: none; }

daviddavid

How did you come up with this number?

daviddavid

How did you come up with this number?

daviddavid

I'm not pleased about all the magic numbers in here. Some of them (like the .btn) could probably use right-alignment …

daviddavid

Can you combine these into one rule?

daviddavid

Can you just use .rb-icon-delete for your elements? I don't like having duplicate names for icons.

daviddavid

Could just use a // single-line comment.

daviddavid

This should use ===

daviddavid

Instead of spelling out "index" and "element", it's just as clear and quicker to read to use "i" and "el"

daviddavid

These two lines should be combined (} else {)

daviddavid

It might be worth assigning the selector (or selector string) to a variable to reduce the length of this line.

daviddavid

Can you combine these into a single var statement? var selectionData = ..., widgetCheckbox = ...;

daviddavid

If you combine the first two lines into one, you'd save some indentation (and even if you don't, there's some …

daviddavid

This line needs a semicolon.

daviddavid

Please wrap this string in gettext(...)

daviddavid

This will run the selector three times. You should chain this as such: $('#' + widgetID) .removeClass('widget-masonry-item') .parent() .masonry('reload') .end() …

daviddavid

Add a space between the // and the comment.

daviddavid

Add a space between the // and the comment.

daviddavid

This should use ===

daviddavid

You call $(element) twice. It would be nice to assign that to a variable so you only have to run …

daviddavid

It looks like you're calling append() and passing in a selector? I'm not sure what this does.

daviddavid

This should use ===

daviddavid

No spaces inside of the parens.

daviddavid

No spaces inside of the parens.

daviddavid

"Save Widgets" should be localized. Probably you'll need to do that beforehand, like this: function createWidgetAdderModals() { var buttonText = …

daviddavid

It looks like this code will result in four HTTP requests (and possibly two confirm() dialogs)? Can we maybe rewire …

daviddavid

Careful about trailing whitespace.

daviddavid

Can you wrap this comment to be as close to 80 columns on the first line as you can?

daviddavid

Space between the // and the comment.

daviddavid

All variables should be declared at the beginning of the function, even if you wait until here to assign them …

daviddavid

Space between the // and the comment.

daviddavid

Should use ===.

daviddavid

It's old code, but this could be simplified to use {{widget.collapsed|yesno:"expand,collapse"}} instead of the if/else.

daviddavid

This hsould be marked for translation.

daviddavid

Mark for translation.

daviddavid

Combine these together (} else {)

daviddavid

Template tags like this should all be left-aligned, and should operate on a sort of separate indentation "namespace" than the …

daviddavid
HE
HE
HE
HE
HE
HE
HE
david
  1. 
      
  2. reviewboard/admin/views.py (Diff revision 2)
     
     
     
     
     
    Show all issues

    This could be a bit more efficient. You can either do a single for p in primary_widgets and then append to two lists, or you could use itertools like this:

    # This at the top:
    from itertools import groupby
    
    ...
    
    # and then here:
    grouped = groupby(
        primary_widgets,
        lambda p: primary_widget_selections[p.widget_id] == '1')
    selected_primary_widgets = grouped[True]
    unselected_primary_widgets = grouped[False]
    
  3. reviewboard/admin/views.py (Diff revision 2)
     
     
     
     
     
    Show all issues

    Same here about iterating over the list twice.

  4. reviewboard/admin/views.py (Diff revision 2)
     
     
     
     
     
     
     
    Show all issues

    If several widgets don't have given positions, won't this result in several of the values in positions being set to the same thing (len(widgets))? Is that a problem?

    If not, I'd like to see that reflected in your testing, and some comment about how it's handled added here.

  5. reviewboard/static/rb/css/icons.less (Diff revision 2)
     
     
    Show all issues

    Can you just use .rb-icon-delete for your elements? I don't like having duplicate names for icons.

    1. I used a different name because Christian was planning to make a new icon for removing widgets, so he suggested that I just use a new name as a placeholder for now.

    2. Can you add a comment to that effect, then? It would also be nice to add it at the end of the existing ones here instead of in the middle.

  6. reviewboard/static/rb/js/admin.js (Diff revision 2)
     
     
    Show all issues

    It might be worth assigning the selector (or selector string) to a variable to reduce the length of this line.

  7. reviewboard/static/rb/js/admin.js (Diff revision 2)
     
     
    Show all issues

    Please wrap this string in gettext(...)

  8. reviewboard/static/rb/js/admin.js (Diff revision 2)
     
     
     
     
     
    Show all issues

    This will run the selector three times. You should chain this as such:

    $('#' + widgetID)
        .removeClass('widget-masonry-item')
        .parent()
            .masonry('reload')
            .end()
        .hide();
    
  9. reviewboard/static/rb/js/admin.js (Diff revision 2)
     
     
    Show all issues

    No spaces inside of the parens.

  10. reviewboard/static/rb/js/admin.js (Diff revision 2)
     
     
    Show all issues

    No spaces inside of the parens.

  11. reviewboard/static/rb/js/admin.js (Diff revision 2)
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
    Show all issues

    It looks like this code will result in four HTTP requests (and possibly two confirm() dialogs)? Can we maybe rewire things to get that down to one?

    1. I'm not calling four HTTP requests at the same time though. An HTTP request is called when a widget is removed, or when the user selects all the widgets he wants to add from the modal. Only 1 confirm dialog appears when the user chooses to remove a widget.

  12. reviewboard/static/rb/js/admin.js (Diff revision 2)
     
     
    Show all issues

    Careful about trailing whitespace.

  13. Show all issues

    It's old code, but this could be simplified to use {{widget.collapsed|yesno:"expand,collapse"}} instead of the if/else.

  14. Show all issues

    This hsould be marked for translation.

  15. Show all issues

    Mark for translation.

  16. 
      
david
  1. 
      
  2. Show all issues

    How did you come up with this number?

  3. Show all issues

    How did you come up with this number?

  4. reviewboard/static/rb/css/admin-dashboard.less (Diff revision 2)
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
    Show all issues

    I'm not pleased about all the magic numbers in here. Some of them (like the .btn) could probably use right-alignment instead of left to make it more sensible. Other (like the image widths) would be nice to define in a variable.

  5. 
      
HE
HE
HE
HE
david
  1. 
      
  2. reviewboard/admin/views.py (Diff revisions 2 - 3)
     
     
    Show all issues

    Add a space between the # and the comment.

  3. reviewboard/static/rb/css/admin-dashboard.less (Diff revisions 2 - 3)
     
     
     
     
     
     
     
     
    Show all issues

    Can you combine these two into one rule?

    #all-primary-widgets, #all-secondary-widgets {
      display: none;
    }
    
  4. reviewboard/static/rb/css/admin-dashboard.less (Diff revisions 2 - 3)
     
     
     
     
     
     
     
     
    Show all issues

    Can you combine these into one rule?

  5. reviewboard/static/rb/css/icons.less (Diff revisions 2 - 3)
     
     
     
     
    Show all issues

    Could just use a // single-line comment.

  6. reviewboard/static/rb/js/admin.js (Diff revisions 2 - 3)
     
     
    Show all issues

    This should use ===

  7. reviewboard/static/rb/js/admin.js (Diff revisions 2 - 3)
     
     
     
     
     
     
     
     
    Show all issues

    Instead of spelling out "index" and "element", it's just as clear and quicker to read to use "i" and "el"

  8. reviewboard/static/rb/js/admin.js (Diff revisions 2 - 3)
     
     
     
    Show all issues

    These two lines should be combined (} else {)

  9. reviewboard/static/rb/js/admin.js (Diff revisions 2 - 3)
     
     
     
    Show all issues

    Can you combine these into a single var statement?

    var selectionData = ...,
        widgetCheckbox = ...;
    
  10. reviewboard/static/rb/js/admin.js (Diff revisions 2 - 3)
     
     
     
     
     
     
     
    Show all issues

    If you combine the first two lines into one, you'd save some indentation (and even if you don't, there's some misalignment in the indentation of the last few lines).

  11. reviewboard/static/rb/js/admin.js (Diff revisions 2 - 3)
     
     
    Show all issues

    This line needs a semicolon.

  12. reviewboard/static/rb/js/admin.js (Diff revisions 2 - 3)
     
     
    Show all issues

    Add a space between the // and the comment.

  13. reviewboard/static/rb/js/admin.js (Diff revisions 2 - 3)
     
     
    Show all issues

    Add a space between the // and the comment.

  14. reviewboard/static/rb/js/admin.js (Diff revisions 2 - 3)
     
     
    Show all issues

    This should use ===

  15. reviewboard/static/rb/js/admin.js (Diff revisions 2 - 3)
     
     
     
     
     
    Show all issues

    You call $(element) twice. It would be nice to assign that to a variable so you only have to run the jquery selector once.

  16. reviewboard/static/rb/js/admin.js (Diff revisions 2 - 3)
     
     
    Show all issues

    It looks like you're calling append() and passing in a selector? I'm not sure what this does.

  17. reviewboard/static/rb/js/admin.js (Diff revisions 2 - 3)
     
     
    Show all issues

    This should use ===

  18. reviewboard/static/rb/js/admin.js (Diff revisions 2 - 3)
     
     
    Show all issues

    "Save Widgets" should be localized. Probably you'll need to do that beforehand, like this:

    function createWidgetAdderModals() {
        var buttonText = gettext("Save Widgets"),
            buttons = {};
    
        buttons[buttonText] = function() {
            ...
        };
        $('#large-widget-modal').dialog({
            ...
            buttons: buttons,
            ...
        });
    
        buttons[buttonText] = function() {
            ...
        };
        ...
    
  19. reviewboard/static/rb/js/admin.js (Diff revisions 2 - 3)
     
     
     
    Show all issues

    Can you wrap this comment to be as close to 80 columns on the first line as you can?

  20. reviewboard/static/rb/js/admin.js (Diff revisions 2 - 3)
     
     
    Show all issues

    Space between the // and the comment.

  21. reviewboard/static/rb/js/admin.js (Diff revisions 2 - 3)
     
     
     
     
    Show all issues

    All variables should be declared at the beginning of the function, even if you wait until here to assign them (due to how javascript does hoisting). If you run jshint on your code it should tell you about that.

  22. reviewboard/static/rb/js/admin.js (Diff revisions 2 - 3)
     
     
    Show all issues

    Space between the // and the comment.

  23. reviewboard/static/rb/js/admin.js (Diff revisions 2 - 3)
     
     
    Show all issues

    Should use ===.

  24. 
      
HE
HE
HE
david
  1. 
      
  2. reviewboard/static/rb/js/admin.js (Diff revision 4)
     
     
     
    Show all issues

    Combine these together (} else {)

  3. Show all issues

    Template tags like this should all be left-aligned, and should operate on a sort of separate indentation "namespace" than the HTML. See reviewboard/templates/reviews/review_request_box.html for a good example. Please fix up all of this throughout this template (which wasn't completely correct to begin with).

  4. 
      
HE
david
  1. Ship It!

  2. 
      
HE
HE
HE
HE
Review request changed
Status:
Completed
Change Summary:
Pushed to master (229d0b9)