• 
      

    The Checklist Extension

    Review Request #5007 — Created Nov. 19, 2013 and submitted

    Information

    rb-extension-pack

    Reviewers

    The Checklist extension allows users to create a checklist when they are reviewing a request. This is useful for cases when there are many things to check for, and the reviewer may want to keep track of them. The app allows:

    • auto creation of a new checklist upon viewing a new review request
    • adding new items to the checklist
    • editing existing items
    • deleting items
    • checking off items
    • undoing checked items
    • minimizing checklist
    • maximizing checklist
    • deleting checklist

    The extension is a seperate Django app, and does not modify any of the Reviewboard code. It can be enabled through the Admin page, in the Extension tab.

    Manual testing on Chrome and Firefox:
    - created checklists by viewing new review requests
    - added items on the checklist
    - deleted items on checklist
    - modified items on checklist
    - checking off items
    - undoing checked items
    - tested on different file attachments but same requests
    - tested on different review requests
    - tested on different users


    Description From Last Updated

    If I click this button, the checklist is permanently deleted. 1) When permanently deleting something, I think we should get …

    mike_conleymike_conley

    Because all your view does is render a template, you can currently use the built-in template view: from django.conf.urls.defaults import …

    daviddavid

    Why do you need this?

    daviddavid

    There's a bunch of cleanup you can do here: In order to properly handle local sites, you should use ReviewRequestResource.get_object …

    daviddavid

    Django provides a nice facility for this: checklist, _ = ReviewChecklist.objects.get_or_create( user=this_user, review_request=this_request)

    daviddavid

    Left-over debug code?

    daviddavid

    Similar comments with how to fetch and name user and review_request as the create method above.

    daviddavid

    Instead of pulling these from kwargs, you can define them in your method signature as optional parameters and then check …

    daviddavid

    Left-over debug code?

    daviddavid

    This should probably check that request.user is the same as the checklist user. Right now this allows anyone to delete …

    daviddavid

    There should be a blank line between these, since 'checklist' is the local module.

    daviddavid

    Instead of having these in the docstring, perhaps define them as help_text on each of the fields?

    daviddavid

    Trailing whitespace.

    daviddavid

    Because your attributes have the same name on the client side as on the server, this should be pretty trivial: …

    daviddavid

    This should use === instead of ==

    daviddavid

    I'm not sure why you have the cehcklist_id field when 'id' will be the same.

    daviddavid

    This looks like left-over debug code?

    daviddavid

    Left-over debug code?

    daviddavid

    Could you just connect the 'change' event on the model to this.render()?

    daviddavid

    Left-over debug code?

    daviddavid

    === null

    daviddavid

    Left-over debug code?

    daviddavid

    Left-over debug code?

    daviddavid

    Left-over debug code?

    daviddavid

    Left-over debug code?

    daviddavid

    Left-over debug code?

    daviddavid

    Alignment is a little bit off here.

    daviddavid

    Leftover debug code.

    daviddavid

    This should also be decorated with @webapi_login_required

    daviddavid

    If you're not using @augment_method_from, you don't need to define this at all (the ones in the Review Board codebase …

    daviddavid

    This should be decorated with @webapi_login_required and @webapi_check_local_site.

    daviddavid

    This should also be decorated with @webapi_check_local_site.

    daviddavid

    When things are in parentheses, they don't need continuation lines (the ). Your code is also wider than 80 columns …

    daviddavid

    1 space between # and the comment.

    daviddavid

    If you wrap the whole conditional in parentheses, you can get rid of the .

    daviddavid

    Space between the # and the comment. Also "checklist" is tyoped.

    daviddavid

    Hmm. Actually, request.user is already a User object. How about this? return checklist.user == request.user

    daviddavid

    Alignment is a bit off here. Should be like this: TemplateHook(self, 'base-scripts-post', 'checklist/template.html', apply_to=[...]) Feel free to wrap the items …

    daviddavid

    We don't put spaces between "function" and "(". Please change that here and in the rest of the implementation.

    daviddavid

    Leftover debug code?

    daviddavid

    This should use ===

    daviddavid

    Leftover debug code?

    daviddavid

    Not being used...

    mike_conleymike_conley

    Not being used...

    mike_conleymike_conley

    Not being used...

    mike_conleymike_conley

    Not being used...

    mike_conleymike_conley

    You don't need Djblets' webapi_login_required, since you already get it from reviewboard.webapi.decorators.

    mike_conleymike_conley

    Not being used...

    mike_conleymike_conley

    Not being used...

    mike_conleymike_conley

    Whoa, conflict. I think you just need reviewboard.webapi.base WebAPIResource - you don't need djblets.webapi.resource's WebAPIResource too.

    mike_conleymike_conley

    Add another blank line here

    daviddavid

    Remove this blank line.

    daviddavid

    The alignment isn't quite right here. How about this: checklist = ReviewChecklist.objects.filter( user=user, review_request=review_request)

    daviddavid

    Indent this line one additional space.

    daviddavid

    Not being used

    mike_conleymike_conley

    Not being used

    mike_conleymike_conley

    Can you wrap these in () instead of using the character?

    daviddavid

    URLHook is not being used.

    mike_conleymike_conley

    ChecklistResource is not being used.

    mike_conleymike_conley

    Remove the space between the key name and the :, and deindent the next two lines one space to match.

    daviddavid

    One additional blank line here.

    daviddavid

    I suggest changing this to use LESS instead of CSS. Then you could nest some of these rules.

    daviddavid

    These should use relative paths, in case static media is hosted at a different path. Given your current layout of …

    daviddavid

    Remove this blank line.

    daviddavid

    Can you add SITE_ROOT + in front of the URL here? SITE_ROOT should already be in the global javascript namespace.

    daviddavid

    Comments about methods should be before the method instead of inside it.

    daviddavid

    Same here about method comments.

    daviddavid

    Because you're passing this as the context for _.each, you shouldn't need to use self.

    daviddavid

    ===

    daviddavid

    Same here w/ method comment.

    daviddavid

    This doesn't just "render", it also creates.

    daviddavid

    Remove this line.

    daviddavid

    If this doesn't have any configuration, and you're not planning on adding it right away, you should clean this up …

    daviddavid

    The new js_bundles stuff might be nice to use here, instead of including them by hand.

    daviddavid

    This should probably be something like "Extension for Review Board which adds checklists for reviewers"

    daviddavid

    This should be you, not None. :)

    mike_conleymike_conley

    I think we can remove this newline.

    mike_conleymike_conley

    var saveOptions

    mike_conleymike_conley

    var saveOptions

    mike_conleymike_conley

    I think you should break this up with string concatenation, like: var response = confirm("This action will delete the entire …

    mike_conleymike_conley

    This can just be: if (response) { }

    mike_conleymike_conley

    var saveOptions

    mike_conleymike_conley

    With the js_bundle stuff, does this still need to be in here?

    mike_conleymike_conley

    Maybe format like: new Checklist.ChecklistView({ user_id: "{{user.pk}}", review_request_id: "{{review_request.id}}" });

    mike_conleymike_conley

    Space after the hashes.

    chipx86chipx86

    Blank line after.

    chipx86chipx86

    Wrap to 79 columns. Also, typo on "reviewing requests" ("revewing requests").

    chipx86chipx86

    It's going to require 2.0, because of all the new bundle stuff.

    chipx86chipx86

    Let's call it an alpha for now, since it's not used in production and would still need real-world testing.

    chipx86chipx86

    This is assigning the Python builtin function called id, which isn't what you want. It should be id. However, this …

    chipx86chipx86

    Make sure your code wraps to 79 chars.

    chipx86chipx86

    No need to do the +. Python will intelligently merge those strings together.

    chipx86chipx86

    Parens aren't needed.

    chipx86chipx86

    Same with parens here and below. Also, no blank lines between the conditionals when they're part of the same block. …

    chipx86chipx86

    I'd put this up by has_access_permissions.

    chipx86chipx86

    The register_ and unregister_ should be aligned.

    chipx86chipx86

    Two blank lines.

    chipx86chipx86

    Space before {. Same with some rules below.

    chipx86chipx86

    Space after :. Same with some rules below.

    chipx86chipx86

    You can combine this into one statement.

    chipx86chipx86

    You can inline this: return { user_id: ..., review_request_id: ..., ... };

    chipx86chipx86

    Why did you need to override parse, instead of just providing a parseResourceData? If there's a special reason, it's best …

    chipx86chipx86

    No need to define options. Backbone will ignore it and overwrite it. Instead, what you should do is pull out …

    chipx86chipx86

    Remove the trailing comma. Some browsers will complain about this otherwise.

    chipx86chipx86

    Should align these.

    chipx86chipx86

    Best to define a template on the view and use that: template: _.template([ '<p>...</p>', '<a>...</a>', ... ].join('')), ... this.$el.html(this.template());

    chipx86chipx86

    You can use method chaining: $('#checklist_toggle_size') .css(...) .attr(...);

    chipx86chipx86

    No need to quote this.

    chipx86chipx86

    Missing a var statement.

    chipx86chipx86

    Blank line isn't needed.

    chipx86chipx86

    Should align these.

    chipx86chipx86

    You shoud be able to make use of the bundles now. I think you mentioned it during a meeting. Also, …

    chipx86chipx86

    Spaces after the colon.

    chipx86chipx86
    david
    1. I haven't looked at any of the code yet, but you can close /r/4738 and /r/4668 as "Discarded" now.

    2. 
        
    david
    1. 
        
    2. checklist/checklist/admin_urls.py (Diff revision 1)
       
       
      Show all issues

      Because all your view does is render a template, you can currently use the built-in template view:

      from django.conf.urls.defaults import patterns, url
      from django.views.generic import TemplateView
      
      urlpatterns = patterns(
          '',
      
         url(r'^$', TemplateView.as_view(template_name="configure.html")),
      )
      

      You can then get rid of your views.py entirely.

    3. checklist/checklist/checklistResource.py (Diff revision 1)
       
       
       
       
       
       
      Show all issues

      Why do you need this?

      1. I'm not entirely sure why, but when I implement has_access_permissions to return True, doing a 'GET' results in an XML file download. This is how I tried to implement has_access_permissions:

        def has_access_permissions(self, request, checklist, *args, **kwags):
            this_user = User.objects.filter(pk=request.user.pk)[0]
            return checklist.user == this_user
        

        And then a 'GET' call would result in a file that looks like this: http://pastie.org/8499554

        The checklist itself doesn't require 'GET' to be implemented, but I'm just using 'GET' for debugging purposes, to see if my changes on the checklist are getting implemented.

      2. How did you do the GET?

        The API supports both XML and JSON formats. If you access it through something that prefers XML (say, just opening the page in a web browser) you'll get the XML.

      3. Ah yes, that's how I do my GET. I see, I understand now.

    4. checklist/checklist/checklistResource.py (Diff revision 1)
       
       
       
       
       
      Show all issues

      There's a bunch of cleanup you can do here:

      • In order to properly handle local sites, you should use
        ReviewRequestResource.get_object to fetch the ReviewRequest.
        This means you'll have to import that resource.

      ReviewRequestResource.get_object takes in review_request_id
      and local_site_name parameters, which are helpfully already
      in your kwargs. You can leave them in there and just pass the
      whole kwargs to get_object().

      • The user_id field can be a parameter to your function.
      • I'd rename 'this_user' and 'this_request' to be 'user' and 'review_request', respectively.

      The new code might look something like this:

      ```python

      ... way up top:
      from reviewboard.webapi.resources import resources

      ... and down here:

      def create(self, request, user_id=None, args, kwargs):
      user = User.objects.get(pk=user_id)
      review_request = resources.review_request.get_object(
      request,
      args, **kwargs)

    5. checklist/checklist/checklistResource.py (Diff revision 1)
       
       
       
       
       
       
       
       
       
       
       
       
      Show all issues

      Django provides a nice facility for this:

      checklist, _ = ReviewChecklist.objects.get_or_create(
          user=this_user,
          review_request=this_request)
      
    6. checklist/checklist/checklistResource.py (Diff revision 1)
       
       
       
      Show all issues

      Left-over debug code?

      1. Thanks! I'll fix these soon. And I didn't realize so much of the debug code are still here. I removed them at school, but I must have forgotten to update my repo at home. =)

    7. checklist/checklist/checklistResource.py (Diff revision 1)
       
       
       
       
       
      Show all issues

      Similar comments with how to fetch and name user and review_request as the create method above.

    8. checklist/checklist/checklistResource.py (Diff revision 1)
       
       
       
      Show all issues

      Instead of pulling these from kwargs, you can define them in your method signature as optional parameters and then check against None:

      def update(self, request, checklist_id,
                 checklist_item_id=None, item_description=None):
          ...
      
          if (checklist_item_id is None and
                  item_description is not None):
              checklist.add_item(item_description)
      

      Similar for the other things below that you use kwargs for.

    9. Show all issues

      Left-over debug code?

    10. checklist/checklist/checklistResource.py (Diff revision 1)
       
       
       
      Show all issues

      This should probably check that request.user is the same as the checklist user. Right now this allows anyone to delete anyone else's checklist.

    11. checklist/checklist/extension.py (Diff revision 1)
       
       
       
      Show all issues

      There should be a blank line between these, since 'checklist' is the local module.

    12. checklist/checklist/models.py (Diff revision 1)
       
       
       
       
       
       
       
       
      Show all issues

      Instead of having these in the docstring, perhaps define them as help_text on each of the fields?

    13. checklist/checklist/models.py (Diff revision 1)
       
       
      Show all issues

      Trailing whitespace.

    14. checklist/checklist/static/js/models/checklistAPI.js (Diff revision 1)
       
       
       
       
       
       
       
       
       
       
       
       
       
       
      Show all issues

      Because your attributes have the same name on the client side as on the server, this should be pretty trivial:

      ```javascript
      toJSON: function() {
      return this.attributes;
      },
      ````

      1. This gives me 400 Bad Request for some reason.

      2. There's a bunch of internal attributes as part of a model that will fail request parameter validation. You'll need to build it yourself.

        You shouldn't need all the conditionals, though. Shouldn't those have valid values?

        A trick for essentially turning a null to a non-entry (which I believe the AJAX code will skip when submitting the request) is to do:

        return {
            checklist_id: this.get('checklist_id') || undefined,
            ...
        }
        

        Still, though, I think it's best to ensure these all have valid values when making a request, and serializing all supported values.

      3. Yeah, sometimes I turn some of those variables to null on purpose. For example, if I edit the description of a checklist item, checklist_item_id would be set. But when I'm adding a new item, checklist_item_id should be reset to null, because the item hasn't been created yet.

        I'll try your suggestion.

    15. Show all issues

      This should use === instead of ==

    16. Show all issues

      I'm not sure why you have the cehcklist_id field when 'id' will be the same.

    17. checklist/checklist/static/js/views/checklistView.js (Diff revision 1)
       
       
       
       
       
       
       
       
       
      Show all issues

      This looks like left-over debug code?

    18. Show all issues

      Left-over debug code?

    19. Show all issues

      Could you just connect the 'change' event on the model to this.render()?

      1. Hmm... I'm not sure how to connect it exactly.

        I tried 'change this.model': 'render', but it never gets rendered after the item is modified.

      2. In your view's initialize function, you'd do something like this:

        this.listenTo(this.model, 'change', this.render);
        
    20. Show all issues

      Left-over debug code?

    21. Show all issues

      === null

    22. Show all issues

      Left-over debug code?

    23. Show all issues

      Left-over debug code?

    24. checklist/checklist/static/js/views/checklistView.js (Diff revision 1)
       
       
       
       
       
       
       
       
       
      Show all issues

      Left-over debug code?

    25. Show all issues

      Left-over debug code?

    26. Show all issues

      Left-over debug code?

    27. 
        
    LE
    david
    1. Can you move the image files into "static/images/" ?

    2. checklist/checklist/checklistResource.py (Diff revision 2)
       
       
       
       
      Show all issues

      Alignment is a little bit off here.

    3. Show all issues

      Leftover debug code.

    4. Show all issues

      This should also be decorated with @webapi_login_required

    5. checklist/checklist/checklistResource.py (Diff revision 2)
       
       
       
       
      Show all issues

      If you're not using @augment_method_from, you don't need to define this at all (the ones in the Review Board codebase that use augment use it to override the docstring)

    6. Show all issues

      This should be decorated with @webapi_login_required and @webapi_check_local_site.

    7. Show all issues

      This should also be decorated with @webapi_check_local_site.

    8. checklist/checklist/checklistResource.py (Diff revision 2)
       
       
       
      Show all issues

      When things are in parentheses, they don't need continuation lines (the ). Your code is also wider than 80 columns here, which we try to avoid.

    9. Show all issues

      1 space between # and the comment.

    10. checklist/checklist/checklistResource.py (Diff revision 2)
       
       
       
      Show all issues

      If you wrap the whole conditional in parentheses, you can get rid of the .

    11. Show all issues

      Space between the # and the comment. Also "checklist" is tyoped.

    12. checklist/checklist/checklistResource.py (Diff revision 2)
       
       
       
      Show all issues

      Hmm. Actually, request.user is already a User object. How about this?

      return checklist.user == request.user
      
    13. checklist/checklist/extension.py (Diff revision 2)
       
       
       
      Show all issues

      Alignment is a bit off here. Should be like this:

      TemplateHook(self, 'base-scripts-post', 'checklist/template.html',
                   apply_to=[...])
      

      Feel free to wrap the items in the apply_to list to keep things under 80 columns.

    14. Show all issues

      We don't put spaces between "function" and "(". Please change that here and in the rest of the implementation.

    15. Show all issues

      Leftover debug code?

    16. Show all issues

      This should use ===

    17. Show all issues

      Leftover debug code?

    18. 
        
    LE
    david
    1. This review is mostly small style issues.

    2. Show all issues

      Add another blank line here

    3. Show all issues

      Remove this blank line.

    4. checklist/checklist/checklistResource.py (Diff revision 3)
       
       
       
      Show all issues

      The alignment isn't quite right here. How about this:

      checklist = ReviewChecklist.objects.filter(
          user=user, review_request=review_request)
      
    5. Show all issues

      Indent this line one additional space.

    6. checklist/checklist/extension.py (Diff revision 3)
       
       
       
      Show all issues

      Can you wrap these in () instead of using the character?

    7. checklist/checklist/extension.py (Diff revision 3)
       
       
      Show all issues

      Remove the space between the key name and the :, and deindent the next two lines one space to match.

    8. checklist/checklist/models.py (Diff revision 3)
       
       
      Show all issues

      One additional blank line here.

    9. Show all issues

      I suggest changing this to use LESS instead of CSS. Then you could nest some of these rules.

    10. Show all issues

      These should use relative paths, in case static media is hosted at a different path. Given your current layout of static media, probably url('../plus.png')

      I still think you should move images into a static/images/ directory.

    11. Show all issues

      Remove this blank line.

    12. Show all issues

      Can you add SITE_ROOT + in front of the URL here? SITE_ROOT should already be in the global javascript namespace.

    13. Show all issues

      Comments about methods should be before the method instead of inside it.

    14. Show all issues

      Same here about method comments.

    15. Show all issues

      Because you're passing this as the context for _.each, you shouldn't need to use self.

    16. Show all issues

      ===

    17. Show all issues

      Same here w/ method comment.

    18. Show all issues

      This doesn't just "render", it also creates.

    19. Show all issues

      Remove this line.

    20. Show all issues

      If this doesn't have any configuration, and you're not planning on adding it right away, you should clean this up and remove this, the url, and the is_configurable flag.

    21. Show all issues

      The new js_bundles stuff might be nice to use here, instead of including them by hand.

    22. checklist/setup.py (Diff revision 3)
       
       
      Show all issues

      This should probably be something like "Extension for Review Board which adds checklists for reviewers"

    23. 
        
    mike_conley
    1. I've been fiddling with your extension this week, Elaine. Very cool. :) Just some notes...

    2. Show all issues

      If I click this button, the checklist is permanently deleted.

      1) When permanently deleting something, I think we should get the user to confirm this choice before carrying it out.

      2) How do I use a checklist again if I've deleted it? How can I start using a checklist again?

      1. 2) Hmm... yeah, I'm not sure whether my implementation for that is suave enough, but a checklist gets created or fetched from the backend every time the user tries to review a request. So a new checklist is created again when the user views a diff/attachment, or simply reloads the page. I think eventually there should be a way for the user to configure when or where he/she wants the checklist to appear.

    3. Show all issues

      Not being used...

    4. Show all issues

      Not being used...

    5. Show all issues

      Not being used...

    6. Show all issues

      Not being used...

    7. Show all issues

      You don't need Djblets' webapi_login_required, since you already get it from reviewboard.webapi.decorators.

    8. Show all issues

      Not being used...

    9. Show all issues

      Not being used...

    10. Show all issues

      Whoa, conflict. I think you just need reviewboard.webapi.base WebAPIResource - you don't need djblets.webapi.resource's WebAPIResource too.

    11. checklist/checklist/extension.py (Diff revision 3)
       
       
      Show all issues

      Not being used

    12. checklist/checklist/extension.py (Diff revision 3)
       
       
      Show all issues

      Not being used

    13. checklist/checklist/extension.py (Diff revision 3)
       
       
      Show all issues

      URLHook is not being used.

    14. checklist/checklist/extension.py (Diff revision 3)
       
       
      Show all issues

      ChecklistResource is not being used.

    15. checklist/setup.py (Diff revision 3)
       
       
      Show all issues

      This should be you, not None. :)

    16. 
        
    mike_conley
    1. Hey Elaine,

      I know you've closed a bunch of these issues, but your posted revision still has them. Have you forgotten to publish your update?

      -Mike

      1. Ah, yes I did forget! Ahh, omg, thanks for reminding me!!

    2. 
        
    LE
    LE
    LE
    mike_conley
    1. Really minor nits from me now, but this looks really good. There are some whitespace issues that you need to clean-up though - just check for the large red blobs in the diff.

    2. Show all issues

      I think we can remove this newline.

    3. Show all issues

      var saveOptions

    4. Show all issues

      var saveOptions

    5. Show all issues

      I think you should break this up with string concatenation, like:

      var response = confirm("This action will delete the entire checklist." +
      "This cannot be undone.");

    6. Show all issues

      This can just be:

      if (response) {
      }

    7. Show all issues

      var saveOptions

    8. Show all issues

      With the js_bundle stuff, does this still need to be in here?

      1. I couldn't get it working yet, so that's why this is still here.

    9. Show all issues

      Maybe format like:

      new Checklist.ChecklistView({
      user_id: "{{user.pk}}",
      review_request_id: "{{review_request.id}}"
      });

    10. 
        
    LE
    LE
    chipx86
    1. Looking good. Got some style stuff to fix up. Sorry I didn't get that feedback to you sooner (my fault).

      Something I recommend is to run the 'pep8' and 'pyflakes' tools on your Python codebase, and the 'jshint' tool on your JavaScript codebase. These are great for finding common style issues and telling you what needs fixing.

      Overall though, this is looking like a valuable extension! Good job :)

    2. checklist/README.md (Diff revision 6)
       
       
      Show all issues

      Space after the hashes.

    3. checklist/README.md (Diff revision 6)
       
       
      Show all issues

      Blank line after.

    4. checklist/README.md (Diff revision 6)
       
       
      Show all issues

      Wrap to 79 columns.

      Also, typo on "reviewing requests" ("revewing requests").

    5. checklist/README.md (Diff revision 6)
       
       
      Show all issues

      It's going to require 2.0, because of all the new bundle stuff.

    6. checklist/README.md (Diff revision 6)
       
       
      Show all issues

      Let's call it an alpha for now, since it's not used in production and would still need real-world testing.

    7. Show all issues

      This is assigning the Python builtin function called id, which isn't what you want. It should be id. However, this is the default, so I think you can just remove the line.

    8. Show all issues

      Make sure your code wraps to 79 chars.

    9. Show all issues

      No need to do the +. Python will intelligently merge those strings together.

    10. Show all issues

      Parens aren't needed.

    11. checklist/checklist/checklistResource.py (Diff revision 6)
       
       
       
      Show all issues

      Same with parens here and below.

      Also, no blank lines between the conditionals when they're part of the same block. So:

      if foo:
          ...
      elif bar:
          ...
      
    12. checklist/checklist/checklistResource.py (Diff revision 6)
       
       
       
      Show all issues

      I'd put this up by has_access_permissions.

    13. checklist/checklist/extension.py (Diff revision 6)
       
       
       
      Show all issues

      The register_ and unregister_ should be aligned.

    14. checklist/checklist/extension.py (Diff revision 6)
       
       
       
       
      Show all issues

      Two blank lines.

    15. Show all issues

      Space before {.

      Same with some rules below.

    16. Show all issues

      Space after :. Same with some rules below.

    17. Show all issues

      You can combine this into one statement.

    18. checklist/checklist/static/js/models/checklistAPI.js (Diff revision 6)
       
       
       
       
       
       
       
      Show all issues

      You can inline this:

      return {
          user_id: ...,
          review_request_id: ...,
          ...
      };
      
    19. Show all issues

      Why did you need to override parse, instead of just providing a parseResourceData? If there's a special reason, it's best to document it.

    20. checklist/checklist/static/js/views/checklistView.js (Diff revision 6)
       
       
       
       
       
       
      Show all issues

      No need to define options. Backbone will ignore it and overwrite it.

      Instead, what you should do is pull out every option you care about inside initialize below. It'll be passed in an options variable containing what was passed to the view. You can set each of these on this.

      The next version of Backbone.js will remove the automatic assignment of this.options, so it's important. (We still need to update our code to do this as well).

      Same for other views.

    21. Show all issues

      Remove the trailing comma. Some browsers will complain about this otherwise.

    22. Show all issues

      Should align these.

    23. checklist/checklist/static/js/views/checklistView.js (Diff revision 6)
       
       
       
       
       
      Show all issues

      Best to define a template on the view and use that:

      template: _.template([
          '<p>...</p>',
          '<a>...</a>',
          ...
      ].join('')),
      

      ...
      

      this.$el.html(this.template());
      
    24. Show all issues

      You can use method chaining:

      $('#checklist_toggle_size')
          .css(...)
          .attr(...);
      
    25. Show all issues

      No need to quote this.

    26. Show all issues

      Missing a var statement.

    27. Show all issues

      Blank line isn't needed.

    28. Show all issues

      Should align these.

    29. Show all issues

      You shoud be able to make use of the bundles now. I think you mentioned it during a meeting.

      Also, /static/ isn't always going to be a valid path. Bundles will take care of the path for you, but if you were to use your own script and link tags, you'd need to do:

      {% static "ext/checklist.extension.Checklist/..." %}
      

      That will ensure you have the right path for the configuration.

      1. Okay, I'll do the static one for now, because I can't get the bundles working, but I'll return to it a bit later.

    30. Show all issues

      Spaces after the colon.

    31. 
        
    LE
    LE
    david
    1. I'm going to push this to a branch in the rb-extension-pack repo so that it's easier for future contributors to work on it.

    2. 
        
    LE
    Review request changed
    Status:
    Completed
    Change Summary:
    Pushed to rb-extension-pack/checklist (c97ce7b). Thanks!