How do I customize results from vaadin-upload polymer component?

527 views Asked by At

I have a server side service that receives file uploads and does validations on the contents of the zip files. The validation may include multiple messages with the type being success, warning and error.

Here is the current code in my polymer component using vaadin-upload that I am using:

window.addEventListener('WebComponentsReady', function() {
    var upload = document.querySelector('vaadin-upload#responseDemo');

    upload.addEventListener('upload-response', function(event) {
        var results = JSON.parse(event.detail.xhr.response);
        console.log('upload xhr after server response: ', event.detail.xhr);

        if (results[0].messages.length > 0) {
            event.detail.file.error = "";
            for (var i = 0; i < results[0].messages.length; i++) {
                if (i > 0) {
                    event.detail.file.error += ";";
                }
                event.detail.file.error += results[0].messages[i].message;
            }
        }

        // Interpret any server response as success:
        // event.detail.xhr.status = 200;
    });
});

Here is the format of the results coming back from the service:

[
    {
        "name": "foo.zip",
        "messages": [
            {
                "type": "error",
                "message": "no store.csv metadata found"
            }
        ]
    }
]

If there are any messages of type error, then it should show failure for the upload of the file. If there are only warnings and successes, then the upload should have an icon with the warning. If there are no messages or messages of only success, then the file upload should be marked as success.

I am currently using polymer 1, but will be upgrading to polymer 3 soon.

1

There are 1 answers

0
Loren Cahlander On BEST ANSWER

I found the answer. Here is the template:

      <paper-dialog class="wide" id="dialog">
        <h2>Upload ZIP(s)</h2>
        <paper-dialog-scrollable>
          <vaadin-upload accept=".rdf" target="modules/upload.xq" method="POST" timeout="300000" form-data-name="my-attachment" id="responseDemo" files="{{files}}">
            <iron-icon slot="drop-label-icon" icon="description"></iron-icon>
            <span slot="drop-label">Drop your requests here (RDF files only)</span>
            <div slot="file-list">
              <h4 id="files">Files</h4>
              <template is="dom-repeat" items="[[files]]" as="file">
                <upload-item item="[[file]]"></upload-item>
              </template>
            </div>
          </vaadin-upload>
        </paper-dialog-scrollable>
        <div class="buttons">
          <paper-button on-click="_closeUpload">Close</paper-button>
        </div>
      </paper-dialog>

Here is the upload-item custom component.

import {PolymerElement, html} from '@polymer/polymer/polymer-element.js';
import '@vaadin/vaadin-grid/vaadin-grid.js';
import '@vaadin/vaadin-progress-bar/vaadin-progress-bar.js';
import '@polymer/iron-icon/iron-icon.js';

/**
 * @customElement
 * @polymer
 */
class UploadItem extends PolymerElement {
  static get template() {
    return html`
    <style is="custom-style">
      :host {
        display: block;
        }
      .card-content {
        width: 100%;
      }
      .term {
        font-size: 14px;
      }
      vaadin-grid {
        overflow: right;
      }

      </style>
      <div class="card-content">
        <span class="term">[[item.filename]]</span>
        <span class="term">[[item.responseFilename]]</span>
        <template is="dom-if" if="[[item.status]]">
          <b>[[item.status]]</b>
          <vaadin-progress-bar indeterminate value="0"></vaadin-progress-bar>
        </template>
        <template is="dom-if" if="[[item.location]]">
          <a href="[[item.location]]" download="[[item.responseFilename]]"><iron-icon class="download" icon="icons:file-download"></iron-icon></a>
        </template>
        <vaadin-grid  theme="compact wrap-cell-content column-borders row-stripes" items="[[item.messages]]"  height-by-rows>
          <vaadin-grid-column flex-grow="1">
            <template class="header">Type</template>
            <template>[[item.type]]</template>
          </vaadin-grid-column>
          <vaadin-grid-column flex-grow="7">
            <template class="header">Message</template>
            <template>[[item.message]]</template>
          </vaadin-grid-column>
        </vaadin-grid>
      </div>
    `;
  }
  static get properties() {
    return {
      item: { type: Object, notify: true }
    };
  }


}

window.customElements.define('upload-item', UploadItem);

Here is the javascript to open the upload dialog.

    _openDialog() {
      var d = this.$.dialog;
      var upload = this.$.responseDemo;

      upload.addEventListener('upload-response', function(event) {
        var results = JSON.parse(event.detail.xhr.response);
        console.log('upload xhr after server response: ', event.detail.xhr);

        if (results.errorResponse) {
          event.detail.file.messages = [{'type': 'fatal', 'message': results.errorResponse.message }];
        } else {
          if (results[0].responseFilename) {
            event.detail.file.responseFilename = results[0].responseFilename;
            event.detail.file.location = results[0].location;
            if (results[0].messages.length) {
              event.detail.file.messages = results[0].messages;
            }
          }
        }
      });
      this.$.dialog.open();
    }