This series is a revision to the previous version of the patch series 
[1]. Following comments, the counter for the number of objects in the 
update message is fixed. Also, errors when fetching are now caught in 
rest.js and added to the list of error messages. This resolves the case
where a network failure doesn’t give feedback to the user of what 
happened to their action. 

Since v1, the following changes:
- Patch 1: 
  - fix bullets showing up for message and errors containers
  - move errors container to base.html
  - add background color to errors container to appear as a continuation
    of the messages element
- Patch 2: nothing, reviewed by dja
- Patch 3: fix update message counter and handle fetch request errors

[1] https://lists.ozlabs.org/pipermail/patchwork/2021-August/007093.html
[2] https://lists.ozlabs.org/pipermail/patchwork/2021-August/007100.html

Raxel Gutierrez (3):
  messages: clean up messages and errors containers
  static: add JS Cookie library to get csrftoken for client-side
    requests
  static: add rest.js to handle PATCH requests & respective responses

 htdocs/README.rst                             |   9 ++
 htdocs/css/style.css                          |  43 +++++--
 htdocs/js/js.cookie.min.js                    |   2 +
 htdocs/js/rest.js                             | 110 ++++++++++++++++++
 patchwork/templates/patchwork/list.html       |  10 --
 .../patchwork/user-link-confirm.html          |   5 +-
 patchwork/templates/patchwork/user-link.html  |   4 +-
 templates/base.html                           |  31 +++--
 8 files changed, 180 insertions(+), 34 deletions(-)
 create mode 100644 htdocs/js/js.cookie.min.js
 create mode 100644 htdocs/js/rest.js

Range-diff against v1:
1:  31a065c6 ! 1:  9087ddbe messages: clean up messages and errors containers
    @@ Commit message
         concept, customize the text color of each existing message level. Also,
         this addition resolves a TODO by stephenfin in the previous code.
     
    -    Modularize the errors container with a new partial template errors.html
    -    that makes it easier to reuse errors in various pages. These changes
    -    make the code more readable and ready for change.
    +    Move the errors container after the messages container in the DOM in 
the
    +    base.html template so that every template can share the same errors
    +    container. Also, add a background color to the errors container so that
    +    both containers blend in as a uniform block. Add bullet points to each
    +    error item in the list of errors.
     
         Change both the messages and errors containers to always exist in
         the DOM. With this, the addition of update and error messages is 
simpler
    @@ Commit message
     
         [1] 
https://docs.djangoproject.com/en/3.2/ref/contrib/messages/#message-tags
     
    -    Signed-off-by: Raxel Gutierrez <ra...@google.com>
    -
      ## htdocs/css/style.css ##
     @@
     +:root {
    @@ htdocs/css/style.css: dl dt {
     -#messages {
     +.messages {
          background: #e0e0f0;
    -     margin: 0.5em 1em 0.0em 0.5em;
    +-    margin: 0.5em 1em 0.0em 0.5em;
    ++    margin: 0.5em 1em 0.0em 1em;
          padding: 0.3em;
    - }
    - 
    --#messages .message {
    --    color: green;
    ++    list-style-type: none;
    ++}
    ++
     +.messages:empty {
     +    display: none;
     +}
    @@ htdocs/css/style.css: dl dt {
     +
     +.messages .warning {
     +    color: var(--warning-color);
    -+}
    -+
    + }
    + 
    +-#messages .message {
    +-    color: green;
     +.messages .error {
     +    color: var(--danger-color);
      }
    @@ htdocs/css/style.css: table.loginform {
      
      /* form errors */
     -.errorlist {
    -+.error-list {
    +-    color: red;
    +-    list-style-type: none;
    +-    padding-left: 0.2em;
    +-    margin: 0em;
    ++#errors {
    ++    background: #e0e0f0;
    ++    margin: 0em 1em 0.5em 1em;
    ++    padding: 0.3em;
    + }
    +-.error {
    ++
    ++#errors:empty {
    ++    display: none;
    ++}
    ++
    ++.error-list, .errorlist {
          color: red;
    -     list-style-type: none;
    -     padding-left: 0.2em;
    + }
    + 
     
      ## patchwork/templates/patchwork/list.html ##
     @@
    @@ patchwork/templates/patchwork/list.html
     -{% endfor %}
     -</ul>
     -{% endif %}
    -+{% include "patchwork/partials/errors.html" %}
    - 
    +-
      {% include "patchwork/partials/patch-list.html" %}
      
    + {% endblock %}
     
    - ## patchwork/templates/patchwork/partials/errors.html (new) ##
    -@@
    -+<div id="errors">
    -+    {% if errors %}
    -+        <p>The following error{{ errors|length|pluralize:" was,s were" }} 
encountered while updating patches:</p>
    -+        <ul class="error-list">
    -+        {% for error in errors %}
    -+            <li>{{ error }}</li>
    -+        {% endfor %}
    -+        </ul>
    -+    {% endif %}
    -+</div>
    -
    - ## patchwork/templates/patchwork/submission.html ##
    + ## patchwork/templates/patchwork/user-link-confirm.html ##
     @@
      
      {% block body %}
      
    -+{% include "patchwork/partials/errors.html" %}
    -+
    - <div>
    -   {% include "patchwork/partials/download-buttons.html" %}
    -   <h1>{{ submission.name }}</h1>
    +-{% if errors %}
    +-<p>{{ errors }}</p>
    +-{% else %}
    ++{% if not errors %}
    +  <p>You have successfully linked the email address {{ person.email }} to
    +   your Patchwork account</p>
    +-
    + {% endif %}
    + <p>Back to <a href="{% url 'user-profile' %}">your
    +  profile</a>.</p>
     
      ## patchwork/templates/patchwork/user-link.html ##
    -@@ patchwork/templates/patchwork/user-link.html: you.</p>
    +@@
    + on the link provided in the email to confirm that this address belongs to
    + you.</p>
    + {% else %}
    ++   <p>There was an error submitting your link request:</p>
    +    {% if form.errors %}
    +-   <p>There was an error submitting your link request.</p>
          {{ form.non_field_errors }}
         {% endif %}
         {% if error %}
    @@ templates/base.html
     -  {# converted to django.contrib.messages #}
     -   <div class="message">{{ message }}</div>
     -  {% endfor %}
    --  </div>
    --{% endif %}
     +  <!--
     +    spaceless tag is used to remove automatically added whitespace so 
that the container
     +    is truly considered empty by the `:empty` pseudo-class that is used 
for styling
    @@ templates/base.html
     +    {% endfor %}
     +  {% endif %}
     +  </ul>
    ++  <div id="errors">
    ++    {% if errors %}
    ++        <p>The following error{{ errors|length|pluralize:" was,s were" }} 
encountered:</p>
    ++        <ul class="error-list">
    ++        {% for error in errors %}
    ++            <li>{{ error }}</li>
    ++        {% endfor %}
    ++        </ul>
    ++    {% endif %}
    +   </div>
    +-{% endif %}
     +  {% endspaceless %}
        <div id="main-content" class="container-fluid">
      {% block body %}
2:  3cf3a280 ! 2:  c92b0dcd static: add JS Cookie library to get csrftoken for 
client-side requests
    @@ Commit message
         [1] https://docs.djangoproject.com/en/3.2/ref/csrf/#ajax
         [2] https://github.com/js-cookie/js-cookie/releases
     
    -    Signed-off-by: Raxel Gutierrez <ra...@google.com>
    -    Reviewed-by: Daniel Axtens <d...@axtens.net>
    -
      ## htdocs/README.rst ##
     @@ htdocs/README.rst: js
        :GitHub: jQuery plug-in to drag and drop rows in HTML tables
    @@ htdocs/README.rst: js
      ## htdocs/js/js.cookie.min.js (new) ##
     @@
     +/*! js-cookie v3.0.0 | MIT */
    -+!function(e,t){"object"==typeof exports&&"undefined"!=typeof 
module?module.exports=t():"function"==typeof 
define&&define.amd?define(t):(e=e||self,function(){var 
n=e.Cookies,r=e.Cookies=t();r.noConflict=function(){return 
e.Cookies=n,r}}())}(this,(function(){"use strict";function e(e){for(var 
t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)e[r]=n[r]}return 
e}var t={read:function(e){return 
e.replace(/(%[\dA-F]{2})+/gi,decodeURIComponent)},write:function(e){return 
encodeURIComponent(e).replace(/%(2[346BF]|3[AC-F]|40|5[BDE]|60|7[BCD])/g,decodeURIComponent)}};return
 function n(r,o){function i(t,n,i){if("undefined"!=typeof 
document){"number"==typeof(i=e({},o,i)).expires&&(i.expires=new 
Date(Date.now()+864e5*i.expires)),i.expires&&(i.expires=i.expires.toUTCString()),t=encodeURIComponent(t).replace(/%(2[346B]|5E|60|7C)/g,decodeURIComponent).replace(/[()]/g,escape),n=r.write(n,t);var
 c="";for(var u in i)i[u]&&(c+="; 
"+u,!0!==i[u]&&(c+="="+i[u].split(";")[0]));return document.coo
    ++!function(e,t){"object"==typeof exports&&"undefined"!=typeof 
module?module.exports=t():"function"==typeof 
define&&define.amd?define(t):(e=e||self,function(){var 
n=e.Cookies,r=e.Cookies=t();r.noConflict=function(){return 
e.Cookies=n,r}}())}(this,(function(){"use strict";function e(e){for(var 
t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)e[r]=n[r]}return 
e}var t={read:function(e){return 
e.replace(/(%[\dA-F]{2})+/gi,decodeURIComponent)},write:function(e){return 
encodeURIComponent(e).replace(/%(2[346BF]|3[AC-F]|40|5[BDE]|60|7[BCD])/g,decodeURIComponent)}};return
 function n(r,o){function i(t,n,i){if("undefined"!=typeof 
document){"number"==typeof(i=e({},o,i)).expires&&(i.expires=new 
Date(Date.now()+864e5*i.expires)),i.expires&&(i.expires=i.expires.toUTCString()),t=encodeURIComponent(t).replace(/%(2[346B]|5E|60|7C)/g,decodeURIComponent).replace(/[()]/g,escape),n=r.write(n,t);var
 c="";for(var u in i)i[u]&&(c+="; 
"+u,!0!==i[u]&&(c+="="+i[u].split(";")[0]));return 
document.cookie=t+"="+n+c}}return 
Object.create({set:i,get:function(e){if("undefined"!=typeof 
document&&(!arguments.length||e)){for(var 
n=document.cookie?document.cookie.split("; "):[],o={},i=0;i<n.length;i++){var 
c=n[i].split("="),u=c.slice(1).join("=");'"'===u[0]&&(u=u.slice(1,-1));try{var 
f=t.read(c[0]);if(o[f]=r.read(u,f),e===f)break}catch(e){}}return 
e?o[e]:o}},remove:function(t,n){i(t,"",e({},n,{expires:-1}))},withAttributes:function(t){return
 n(this.converter,e({},this.attributes,t))},withConverter:function(t){return 
n(e({},this.converter,t),this.attributes)}},{attributes:{value:Object.freeze(o)},converter:{value:Object.freeze(r)}})}(t,{path:"/"})}));
     
      ## templates/base.html ##
     @@
3:  18aaa0a5 ! 3:  66bd1270 static: add rest.js to handle PATCH requests & 
respective responses
    @@ Commit message
         update messages and vice versa. Consecutive successful update messages
         add to a counter of updated objects. Consecutive error messages stack 
up.
     
    -    Signed-off-by: Raxel Gutierrez <ra...@google.com>
    -
      ## htdocs/js/rest.js (new) ##
     @@
     +/**
    @@ htdocs/js/rest.js (new)
     +            }
     +            handleUpdateMessages(message, success);
     +            return response.ok
    ++        }).catch(error => {
    ++            handleErrorMessages(error);
     +        });
     +}
     +
    @@ htdocs/js/rest.js (new)
     +
     +    // Increment counter of consecutive success update messages
     +    if (messages.firstChild != null) {
    -+        const newMessageCount = 
parseInt(messages.firstChild.textContent.slice(0,1)) + 1
    ++        const currentMessageCount = 
messages.firstChild.textContent.match('^([0-9]+)')[0];
    ++        const newMessageCount = parseInt(currentMessageCount) + 1;
     +        messageContent = newMessageCount + messageContent.slice(1);
     +    }
     +
-- 
2.33.0.rc1.237.g0d66db33f3-goog

_______________________________________________
Patchwork mailing list
Patchwork@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/patchwork

Reply via email to