Allow collapsed entries to fetch data on request

Review Request #11886 — Created Nov. 29, 2021 and updated

Information

Review Board
master

Reviewers

Review Board will collapse old reviews to streamline information.
While the data is visually hidden it will still be computed
and loaded to the client which can cause slowness.

This change makes collapsed review entries get sent to the client
empty, then fetch its content on request. When they expand the entry, we
first check if this entry already has content loaded, if not then load it
by using the new function "fetchEntryUpdates" in reviewRequestPageModel.js
which can trigger an immediate update to load the content of an entry.
This function uses and extends the machinery related to "page pending updates"
In order to make it feel even snappier, I add a mouseover event listener
on the expand button and the expand all button. We start to pull down information
before they even lift the mouse button.

Only load the entry content if the entry is of type "review". Without this restriction,
when they click the expand all button, the entry of type "initial_status_updates" or
"changedesc"also tries to check whether it has content which causes an error.

Created entryViewTests.es6.js that contains test cases for the
behavior of expanding an entry. All tests passed.

Ran all Javascript unit tests and no newly introduced test fails.

Summary ID Author
add console log for debug
e5efe2ddb94478ad7ed00ed9f96d6851a5894d43 Your Name
load the collapsed entry info, finally get it working
6d22271b67203158e4df73ea6aac8003b2cb0467 Your Name
finalize project
62e4b4ccb21a2ad45381f4fafd7164b90a2ca957 Your Name
code clean up
ad5df68ce4b4c6204e2af1aca5cbc3ea8f7addba Your Name
remove white spaces
a729ceb24d2c26f71097e64be3d7580385f84a8c Your Name
remove white space
41ccf48b1b2a3160c3a70a9fac4840eaeecb366e Your Name
review bot issues
e3a0f17e22bfcb4a09cba8a7aa1ca1513d89f535 Your Name
review bot issues
bf3cd0b4df11ae02cb765fdcaa0a2128157d63f5 Your Name
remove white spaces
74d904995f62be003fb653c7c6eb8b814bc4e809 Your Name
remove white spaces
b667b710a6b7d86853fabe942923f25c1db5c2b0 Your Name
Address the comments and issues opened by David on the review request
52273caa718ee0933466cf82195965169ebe1129 Your Name
remove white spaces
1bae1c99c7b799bdbedb30edba3de1f3433207ad Your Name
remove white spaces
ed1bab7a6d126d95ba8968405a9265d4730195c6 Your Name
change test
77205195ee98439162f8971d1d91d1dbf943fd4c Your Name
address issues opened
1fc906713e9341cdea44207ef4d37012d60f217e Your Name
remove space
03e49d2d6fbf68ede0aa21b2cd7aa54ec281f3d0 Your Name
Description From Last Updated

W293 blank line contains whitespace

reviewbotreviewbot

Col: 49 Expected '===' and instead saw '=='.

reviewbotreviewbot

Col: 24 Expected '===' and instead saw '=='.

reviewbotreviewbot

Col: 45 Expected '===' and instead saw '=='.

reviewbotreviewbot

Can you add another paragraph explaining what this means?

daviddavid

Can you add another paragraph explaining what this means?

daviddavid

There's an extra blank line here.

daviddavid

This can use an ES6 template string.

daviddavid

Add spaces after commas here.

daviddavid

Instead of creating a variable for this, let's just define the fat arrow function inline: parsed.load((metadata, html) => this._reloadFromUpdate(entry, metadata, …

daviddavid

Your editor completely reformatted this file to add indentation. Please revert the changes here.

daviddavid

Same with this file.

daviddavid

Add a trailing comma here. Let's also name the function _onToggleCollapseMouseover

daviddavid

Add a space between ) and {

daviddavid

This needs additional spaces: Between if and ( Between ) and {

daviddavid

Use single quotes here.

daviddavid

=== will result in a bool. We don't need the ? true : false

daviddavid

This needs spaces like the if above.

daviddavid

This file got unwanted indentation.

daviddavid

An unwanted space was added at the beginning of this line.

daviddavid

The numbers on the names model, model2, view1, etc. don't really add anything useful, and they're all scoped to the …

daviddavid

This can be const (we only assign to the name once). Same in other test cases.

daviddavid

Some more blank lines in here might make it a little more readable. We can also skip creating a variable …

daviddavid

"give" isn't a typical term used for this kind of function. A better one might be "fetch". How about calling …

chipx86chipx86

urlQueryStr is checking whether urlQuery has anything in it, but we're setting it to something immediately before. We probably can …

chipx86chipx86

I think this function is likely to be more for internal use, so I'd suggest making it private (prefix with …

chipx86chipx86

EntryView shouldn't know what kind of subclasses there will be. In fact, extensions can provide whole new types of entries, …

chipx86chipx86

Based on our naming conventions, this should be templateWithoutBody. Likewise, below should be templateWithBody.

chipx86chipx86

There's an extra sapce at the end of the class list.

chipx86chipx86

Here, too.

chipx86chipx86

And in these spots.

chipx86chipx86

Can you add a blank line between these?

chipx86chipx86

Extra space at the end of the string.

chipx86chipx86

There are extra blank lines at the end of this file. Can you get rid of those?

chipx86chipx86

Can you reorder this to be in alphabetical order? Should be before issueSummaryTableViewTests.

chipx86chipx86

Since you're adding a new block tag, you'll need to indent all the block tags inside by one. For Django …

chipx86chipx86
Checks run (2 failed)
flake8 failed.
JSHint failed.

flake8

JSHint

cynthia
cynthia
david
  1. 
      
  2. Show all issues

    Can you add another paragraph explaining what this means?

  3. Show all issues

    Can you add another paragraph explaining what this means?

  4. Show all issues

    There's an extra blank line here.

  5. Show all issues

    This can use an ES6 template string.

  6. Show all issues

    Add spaces after commas here.

  7. Show all issues

    Instead of creating a variable for this, let's just define the fat arrow function inline:

    parsed.load((metadata, html) =>
        this._reloadFromUpdate(entry, metadata, html));
    
  8. Show all issues

    Your editor completely reformatted this file to add indentation. Please revert the changes here.

  9. reviewboard/static/rb/js/reviewRequestPage/views/changeEntryView.es6.js (Diff revision 2)
     
     
     
     
     
     
     
     
     
     
    Show all issues

    Same with this file.

  10. Show all issues

    Add a trailing comma here. Let's also name the function _onToggleCollapseMouseover

  11. Show all issues

    Add a space between ) and {

  12. Show all issues

    This needs additional spaces:

    • Between if and (
    • Between ) and {
  13. Show all issues

    Use single quotes here.

  14. Show all issues

    === will result in a bool. We don't need the ? true : false

  15. Show all issues

    This needs spaces like the if above.

  16. Show all issues

    This file got unwanted indentation.

  17. Show all issues

    An unwanted space was added at the beginning of this line.

  18. Show all issues

    The numbers on the names model, model2, view1, etc. don't really add anything useful, and they're all scoped to the test body anyway. Since we're just instantiating one per test, let's just call them model and view.

  19. Show all issues

    This can be const (we only assign to the name once). Same in other test cases.

  20. Show all issues

    Some more blank lines in here might make it a little more readable. We can also skip creating a variable for $collapseButton because we only use it once.

  21. 
      
cynthia
chipx86
  1. This looks great! I have suggestions to bring it up to our in-house standards, and a way to better generalize the conditional content loading part. Once fixed up, I think we'll be able to get this into 5.0!

  2. Show all issues

    "give" isn't a typical term used for this kind of function. A better one might be "fetch". How about calling this fetchEntryUpdates?

  3. Show all issues

    urlQueryStr is checking whether urlQuery has anything in it, but we're setting it to something immediately before. We probably can simplify this quite a bit by replacing all this code with:

    const typeID = entry.get('typeID');
    const urlQueryStr = `entries=${typeID}:${entry.id}`;
    

    Nice and simple. No need to join the array, because we only ever have the one entry.

  4. Show all issues

    I think this function is likely to be more for internal use, so I'd suggest making it private (prefix with a _ and group it with other private functions).

  5. Show all issues

    EntryView shouldn't know what kind of subclasses there will be. In fact, extensions can provide whole new types of entries, which may want to load based on their own logic.

    I'd suggest instead keeping state on the model indicating if the entry has been loaded, which would be part of the initial model data on the page. If loaded, have this function do nothing. If not loaded, load it.

    And actually, given that the state would be in the model, and the operation that loads the updates is also in the model, I think this function would be better off in the model. Based on how we often name things, maybe call it ensureContentLoaded. This communicates that the function will load the content if it's needed (and otherwise do nothing — it just ensures that we end up with content one way or another in the end).

    1. Hi Christian, thanks a lot for your detailed code review, I've learned a lot from it!

      I fixed all issues opened except this one. I believe it's a great idea to add a new state "loaded" in the entry model. I moved "ensureContentLoaded" to the model class and I tried to add the "loaded" state to my local branch but had some problems with running it. Sadly, I don't think I get enough time to fix it and add corresponding tests as there are less than two hours left until the pencils down time :(

      I think I'll just keep my current working version of this project without using the load state in the review request. If possible, I'll come back to work on this after I finish all my finals.I would really appreciate your understanding.

    2. I ended up publishing a new WIP review request.

  6. Show all issues

    Based on our naming conventions, this should be templateWithoutBody. Likewise, below should be templateWithBody.

  7. Show all issues

    There's an extra sapce at the end of the class list.

  8. Show all issues

    Here, too.

  9. Show all issues

    And in these spots.

  10. Show all issues

    Can you add a blank line between these?

  11. Show all issues

    Extra space at the end of the string.

  12. Show all issues

    There are extra blank lines at the end of this file. Can you get rid of those?

  13. reviewboard/staticbundles.py (Diff revision 3)
     
     
     
     
    Show all issues

    Can you reorder this to be in alphabetical order? Should be before issueSummaryTableViewTests.

  14. Show all issues

    Since you're adding a new block tag, you'll need to indent all the block tags inside by one.

    For Django templates, we'd do this like:

    {% if not entry.collapsed %}
    {%  if review.body_top ... %}
    {%   blah blah %}
    ...
    {%  endif %}
    {% endif %}
    
  15. 
      
cynthia
cynthia
Review request changed
Description:
   

Review Board will collapse old reviews to streamline information.

    While the data is visually hidden it will still be computed
    and loaded to the client which can cause slowness.

   
   

This change makes collapsed review entries get sent to the client

    empty, then fetch its content on request. When they expand the entry, we
    first check if this entry already has content loaded, if not then load it
~   by using the new function "giveImmediateUpdates" in reviewRequestPageModel.js
  ~ by using the new function "fetchEntryUpdates" in reviewRequestPageModel.js
    which can trigger an immediate update to load the content of an entry.
    This function uses and extends the machinery related to "page pending updates"
    In order to make it feel even snappier, I add a mouseover event listener
    on the expand button and the expand all button. We start to pull down information
    before they even lift the mouse button.

   
   

Only load the entry content if the entry is of type "review". Without this restriction,

    when they click the expand all button, the entry of type "initial_status_updates" or
    "changedesc"also tries to check whether it has content which causes an error.