• 
      

    Add confirmation dialog for post-commit review requests on web UI

    Review Request #10148 — Created Sept. 17, 2018 and submitted

    Information

    Review Board
    release-2.5.x
    9efe7bf...

    Reviewers

    When a user is scrolling through the changeset (post commit review) to
    make a new review request on the web UI, clicking on the row of a
    commit makes a new review request, which can be done accidentally very
    easily.

    I added a confirmation dialog when creating post-commit review requests
    on web UI so the user can confirm that they want to create a new review
    request from that commit. Clicking 'cancel' closes the dialog and takes
    no further action, clicking 'create' creates a new review request.

    Ran JS tests (all of which pass).

    Tested behaviour in Chrome, Safari, and Firefox with the following
    scenarios:

    1. Click on commit, click cancel on confirmation dialog
    2. Click on commit with no diff with master, click confirm, see error
      message
    3. Click on commit with diff with master, click confirm, see review
      request created

    Description From Last Updated

    Can you wrap your summary at 72 characters, but ideally 52 characters. Commit summaries needn't end in a period.

    brennie brennie

    You can have your testing done render a list using: Tested behaviour in Chrome, Safari in Firefox: 1. Something 2. …

    brennie brennie

    The issue was originally filed against reviewboard 2.5.x. Can you apply your patch on that branch, test, and re-post? Note: …

    brennie brennie

    Could you add a screen shot of your work?

    brennie brennie

    Can you wrap your description at 72 characters?

    brennie brennie

    One more request to add to the design of this: can we include the commit summary in the text of …

    david david

    Tiny nit: summaries don't need a period.

    brennie brennie

    Also your summary should be in the imperitive mood as if it were an order. If you substitute your sumamry …

    brennie brennie

    Ideally this long message would be in the body of the dialog instead of the title

    brennie brennie

    How about: "The confirmation dialog will allow the user to cancel the creation of the review request."

    brennie brennie

    We may want to add more context to the message here, something like: You are creating a new review request …

    brennie brennie

    This string needs to be marked for translation with gettext().

    brennie brennie

    This string needs to be marked for translation with gettext(). Missing trailing comma.

    brennie brennie

    This string needs to be marked for translation with gettext().

    brennie brennie

    Unfortunately, we can't use ES6 arrow functions here. We'll have to do _.bind(this._createNewReviewRequest, this) instead. This is because we have …

    brennie brennie

    Instead of doing this, lets define a subclass that will display this content. We can refactor it out into a …

    brennie brennie

    Can you add body and title here? The title should be something like "Are you sure?" or "Create review request?"

    brennie brennie

    This should really be in the default impl of render above. Also, doing _.result twice may result in us calling …

    brennie brennie

    Title case: Create Review Request?

    brennie brennie

    While you're here, would you mind updating the doc comment to take the following format: /** * Initialze the view. …

    brennie brennie

    Need a var body statement at the top of the function.

    brennie brennie

    if (body) {

    brennie brennie

    Instead of duplicating this I would just do See the :js:class:`class-level documentation <RB.DialogView>` for the keys that this object accepts.

    brennie brennie

    Let's sort these alphabetically.

    david david

    Please put a blank line between these two.

    david david

    Instead of <b>, let's just use <span> and then put font-weight: bold in the CSS.

    david david

    Because this is an ES5 file, no trailing comma on the last item in an object.

    david david

    Because this is an ES5 file, no trailing comma on the last item in an object.

    david david

    A few things here. Wrapping everything in gettext wont work. gettext() requires the value to a be a string literal, …

    brennie brennie

    While you're here, can you change this to /**? Otherwise it doesn't get picked up by the documentation generation tool

    brennie brennie

    And this?

    brennie brennie

    This is only used once, so instead of defining a variable, you could do it inline: body: this._dialogBodyTemplate({ prefixText: gettext('...'), …

    david david

    In ES5, all variables need to be defined at the top of the function. So: var commitID = this.model.get('id'), dialogView; …

    david david

    Wrap to 79 columns.

    david david
    shoven
    shoven
    shoven
    brennie
    1. 
        
    2. Show all issues

      Can you wrap your summary at 72 characters, but ideally 52 characters. Commit summaries needn't end in a period.

    3. Show all issues

      You can have your testing done render a list using:

      Tested behaviour in Chrome, Safari in Firefox:
      
      1. Something
      2. Another thing
      3. Yet another thing.
      
    4. Show all issues

      The issue was originally filed against reviewboard 2.5.x.

      Can you apply your patch on that branch, test, and re-post?

      Note:

      To get Reviewboard 2.5.x to work, you will need a new virtual environment with Review Board at release-2.5.x and Djblets at release-0.9.x. You do not need another source checkout of RB or Djblets -- another virtualenv will suffice.

    5. Show all issues

      Could you add a screen shot of your work?

    6. Show all issues

      Can you wrap your description at 72 characters?

      1. You wrapped your description and testing done at 52, which just the 1-line summary needs to be wrapped at.

    7. Show all issues

      How about:

      "The confirmation dialog will allow the user to cancel the creation of the review request."

    8. Show all issues

      We may want to add more context to the message here, something like:

      You are creating a new review request from a commit that has already been published. Are you sure you want to continue?
      
    9. Show all issues

      This string needs to be marked for translation with gettext().

    10. Show all issues

      This string needs to be marked for translation with gettext().

      Missing trailing comma.

    11. Show all issues

      This string needs to be marked for translation with gettext().

    12. Show all issues

      Unfortunately, we can't use ES6 arrow functions here. We'll have to do _.bind(this._createNewReviewRequest, this) instead.

      This is because we have customers on older versions of IE (I know :( ). We do allow arrow functions in .es6.js files, which are transpiled with Babel to ES5 that can run on all these browsers.

      However, since this patch will be backported to 2.5.x, we don't be able to use that. Sorry.

    13. 
        
    shoven
    shoven
    shoven
    brennie
    1. 
        
    2. Show all issues

      Ideally this long message would be in the body of the dialog instead of the title

      1. I tried one approach by adding a 'body' option to the dialogView class to make this change. I'm not sure if this is what you were expecting based on our conversation in Slack, but continuing to use the dialogView class allowed me to take advantage of the existing functionality to set the button list correctly for modalBox. I added a new screenshot of what it looks like now. Let me know what you think.

    3. Show all issues

      Instead of doing this, lets define a subclass that will display this content. We can refactor it out into a generic class at a later date.

      If you wrap the contents of the file in an IIFE, we can have it local to the file.

      1. Can you elaborate on this a bit? I'm not sure I understand exactly what you mean here...

      2. You can ignore this. Your approach is better.

    4. 
        
    shoven
    brennie
    1. 
        
    2. Show all issues

      Can you add body and title here?

      The title should be something like "Are you sure?" or "Create review request?"

    3. reviewboard/static/rb/js/ui/views/dialogView.js (Diff revision 3)
       
       
       
       
      Show all issues

      This should really be in the default impl of render above. Also, doing _.result twice may result in us calling an expensive function twice. Lets do:

      var body;
      
      /* snip */
      
      body = _.result(this, 'body');
      
      if (body !== undefined) {
          this.$el.append($('<p>').text(body));
      }
      
    4. 
        
    shoven
    shoven
    brennie
    1. 
        
    2. Show all issues

      Title case: Create Review Request?

    3. reviewboard/static/rb/js/ui/views/dialogView.js (Diff revision 4)
       
       
       
       
       
       
       
       
       
       
       
       
      Show all issues

      While you're here, would you mind updating the doc comment to take the following format:

      /**
       * Initialze the view.
       * 
       * Args:
       *     options (object):
       *         Options for the view.
       *
       * Option Args:
       *     body (string or function, optional):
       *         <Description of body.>
       *         
       *     title (string, optional):
       *         <Description of title.>
       *
       *     buttons (object, optional):
       *         <Description of buttons.>
       */
      
      1. If you can take a look at what I did, do you think I need to put the parameters of the buttons here like I did even though it's duplicating the description at the top of the file?

    4. Show all issues

      Need a var body statement at the top of the function.

    5. Show all issues

      if (body) {
      
    6. 
        
    david
    1. 
        
    2. Show all issues

      One more request to add to the design of this: can we include the commit summary in the text of the dialog, so people can verify that they clicked on the one they intended to?

      1. I added a screenshot of my changes. I also added the first few characters of the commit id like in the commit view in the list. Let me know what you think.

    3. 
        
    shoven
    shoven
    brennie
    1. 
        
    2. reviewboard/static/rb/js/ui/views/dialogView.js (Diff revision 6)
       
       
       
       
       
       
       
       
       
       
       
       
      Show all issues

      Instead of duplicating this I would just do

      See the :js:class:`class-level documentation <RB.DialogView>` for the keys that this object accepts.
      
    3. 
        
    shoven
    david
    1. Just a few tiny nits left.

    2. reviewboard/static/rb/css/common.less (Diff revision 7)
       
       
       
      Show all issues

      Let's sort these alphabetically.

    3. Show all issues

      Please put a blank line between these two.

    4. Show all issues

      Instead of <b>, let's just use <span> and then put font-weight: bold in the CSS.

    5. Show all issues

      Because this is an ES5 file, no trailing comma on the last item in an object.

      1. In the first review Barret gave me he said I was missing trailing commas so I added them everywhere. So I shouldn't add them unless it's an es6.js file?

      2. That was my bad. I forgot trailing commas in objects aren't an ES5 thing. Sorry 😦

    6. Show all issues

      Because this is an ES5 file, no trailing comma on the last item in an object.

      1. Same thing, in the first review Barret gave me he said I was missing trailing commas so I added them everywhere. So I shouldn't add them unless it's an es6.js file?

    7. 
        
    shoven
    brennie
    1. 
        
    2. Show all issues

      A few things here. Wrapping everything in gettext wont work. gettext() requires the value to a be a string literal, otherwise the code that looks for things to translate won't be able to parse this.

      Also, we want to avoid using inline styles when possible. This should be included in the rules for .summary in the LESS file.

      Instead, lets use a template on the class:

      {
          _dialogTemplate: _.template([
              '<p><%- prefixText %></p>',
              '<p class="summary">',
              ' <%- commitID %>: <%- summary %>',
              '</p>',
              '<p><%- suffixText %></p>',
          ].join('')),
      }
      

      For more details on _.template, check out the docs.

      Then we can use it like so:

      var dialogView = new RB.DialogView({
          title: gettext('Create Review Request?'),
          body: this._dialogTemplate({
              prefixText: gettext('You are creating a new review request from the following published commit:'),
              suffixText: gettext('Are you sure you want to continue?'),
          }), 
          buttons: [ /* ... */ ]
      });
      

      This allows us to only mark the string literals for translation. Additionally, lets use <p> tags for content separation instead of <br>, as that is what they exist for.

    3. 
        
    shoven
    brennie
    1. Two minor nits, but otherwise looks good to me!

    2. Show all issues

      While you're here, can you change this to /**? Otherwise it doesn't get picked up by the documentation generation tool

      1. I changed this for all the functions I touched. Should I fix it for the rest or leave them for now (i.e. it should be in a different patch)

      2. Just the ones you touched are fine. Cleanup can be a different patch.

    3. Show all issues

      And this?

    4. 
        
    brennie
    1. 
        
    2. Show all issues

      Tiny nit: summaries don't need a period.

    3. Show all issues

      Also your summary should be in the imperitive mood as if it were an order. If you substitute your sumamry into the following sentence it should make sense:

      This patch will <summary>
      

      So Add confirmation dialog ... would work or similar.

    4. 
        
    shoven
    david
    1. 
        
    2. Show all issues

      This is only used once, so instead of defining a variable, you could do it inline:

      body: this._dialogBodyTemplate({
          prefixText: gettext('...'),
          commitID: commitID,
          summary: this.model.get('summary'),
          suffixText: ...
      }),
      
    3. Show all issues

      In ES5, all variables need to be defined at the top of the function. So:

      var commitID = this.model.get('id'),
          dialogView;
      
      if (commitID.length > 7) {
          commitID = commitID.slice(0, 7);
      }
      
      dialogView = new RB.DialogView({
          ...
      
    4. Show all issues

      Wrap to 79 columns.

    5. 
        
    shoven
    brennie
    1. Ship It!
    2. 
        
    david
    1. Ship It!
    2. 
        
    shoven
    Review request changed
    Status:
    Completed
    Change Summary:
    Pushed to release-3.0.x (7746104)