controllers_file.js

import Swal from 'sweetalert2';
import byFile from '../views/file/file.html?raw';
import '../views/file/file.css';
import getCsvLists from '../utils/getCsvPropsAndItems.js';

/**
 * @function utilByFile
 * @description Annonymous function to controll and make the logic for the by file view
 * @returns {HTMLElement} - HTML template of Generate view
 */
export default () => {
  const divWrapper = document.createElement('div');
  divWrapper.innerHTML = byFile;

  const conversor = new Conversor(divWrapper);
  conversor.init();
  // logic of this view
  return divWrapper;
};


/**
 * Represents the logic of the by file controller view
 * @class
 * @constructor
 * @param {HTMLElement} htmlContent - The HTML template of the by file view
 * @example
 * const conversor = new Conversor(htmlTemplate);
 */
function Conversor(htmlContent){
  /** @this Conversor */

  /** @member {HTMLElement} */
  this.htmlContent = htmlContent;
  /** @member {HTMLElement} */
  this.dropArea = htmlContent.querySelector('.full-choose__file');
  /** @member {HTMLElement} */
  this.inputFile = htmlContent.querySelector('.input__file');
  /** @member {null} */
  this.files = null;
}

Conversor.prototype = /** @lends Conversor.prototype */ {
  constructor: Conversor,

   /**
   * Init the Conversor by file and add the needed listeners
   * @return {void}
   */
  init(){
    /**
    * Event to generate the translation of the JSON file into CSV file
    * @event inputFile-change
    */
    this.inputFile.addEventListener('change', (e) => this.handleFiles.call(this, e));
    /**
    * Event to generate the translation of the JSON file into CSV file
    * @event dropArea-dragenter
    */
    this.dropArea.addEventListener('dragenter', this.handleEnter.bind(this));
    /**
    * Event to generate the translation of the JSON file into CSV file
    * @event dropArea-drop
    */
    this.dropArea.addEventListener('drop', (e) => this.handleDrop.call(this, e));
    /**
    * Event to generate the translation of the JSON file into CSV file
    * @event dropArea-dragover
    */
    this.dropArea.addEventListener('dragover', (e) => this.handleDragOver.call(this, e));
    /**
    * Event to generate the translation of the JSON file into CSV file
    * @event dropArea-dragleave
    */
    this.dropArea.addEventListener('dragleave', (e) => this.handleLeave.call(this, e));
    /**
    * Event to generate the translation of the JSON file into CSV file
    * @event dropArea-dragexit
    */
    this.dropArea.addEventListener('dragexit', (e) => this.handleLeave.call(this, e));
    /**
    * Event to generate the translation of the JSON file into CSV file
    * @event dropArea-dragend
    */
    this.dropArea.addEventListener('dragend', (e) => this.handleLeave.call(this, e));
  },


  /**
   * Handle the files upload in the input type file
   * @method
   * @fires inputFile-change
   * @param {Event} e Event
   * @return {void}
   */
  handleFiles(e) {
    console.log('Hanlde the file');
    // get the file
    this.files = e.target.files;
    this.processFile(this.files[0]);
  },

   /**
   * Handle dragenter event in the drop area
   * @method
   * @fires dropArea-dragenter
   * @return {void}
   */
  handleEnter(){
    this.dropArea.classList.add('active');
    this.dropArea.textContent = 'Drop to upload the JSON file';
  },

   /**
   * Handle the drop event in the drop area
   * @method
   * @fires dropArea-drop
   * @param {Event} e Event
   * @return {void}
   */
  handleDrop(e){
    e.preventDefault();
    this.dropArea.classList.remove('active');

    // get the file
    this.files = e.dataTransfer.files;
    this.processFile(this.files[0]);
  },

  /**
   * Handle the dragOver event in the drop area
   * @method
   * @fires dropArea-dragover
   * @param {Event} e Event
   * @return {void}
  */
  handleDragOver(e){
    e.preventDefault();
  },

   /**
   * Handle the dragOver event in the drop area
   * @method
   * @fires dropArea-dragleave
   * @fires dropArea-dragend
   * @fires dropArea-dragexit
   * @param {Event} e Event
   * @return {void}
  */
  handleLeave(e){
    e.preventDefault();
    this.dropArea.classList.remove('active');
  },

  /**
   * Process the json file to convert into a csv text format
   * @param {file} file The json file got it to convert into csv
   * @returns {void}
   */
  processFile(file){
    // get the doctype of the file
    const docType = file.type;
    const btnFile = this.htmlContent.querySelector('.btn__choose');
    // get the extension
    const titleFile = file.name.split('.')[0];

    // valid if the file is a .json file
    if(docType === 'application/json'){
      const fileReader = new FileReader();
      // shooting the event load of he fileReader
      fileReader.readAsText(file);

      // load event
      fileReader.addEventListener('load', (e) => {
        // get the csv text format
        const textResult = e.target.result;
        const json = JSON.parse(textResult);
        const jsonList = json.length ? json : [json];
        const [properties, items] = getCsvLists(jsonList);

        const csvText = `${properties.join(',')}\r\n${items.join('\r\n')}`;
        this.buildCsvFile(csvText, titleFile);
      });

      // progress event
      fileReader.addEventListener('progress', (e) => {
        // Evaluating if the progress of the file is ready and make some DOM movement
        if (e.lengthComputable) {
          const intervalId = setInterval(() => {
            const progress = (e.loaded / e.total) * 100;
            btnFile.style.setProperty('--widthAfter', `${progress}%`);
            if(progress === 100) {
              clearInterval(intervalId);
              btnFile.classList.add('file__loaded');
              this.dropArea.style.display = 'none';
              btnFile.setAttribute('for', '');
              btnFile.innerHTML = 'Click to convert another file';
              btnFile.addEventListener('click', () => window.location.reload());
            }
          }, 0);
        }
      });
      return;
    }
    // Is not a valid doctype file
    Swal.fire({
      title: 'Error to convert',
      text: 'Verify your doctype file that you try to upload',
      confirmButtonText: 'Ok',
      icon: 'error',
      backdrop: true,
      width: '70%',
      padding: '1rem',
      position: 'center',
      allowOutsideClick: true,
      allowEscapeKey: true,
      confirmButtonAriaLabel: 'Confirmar'

    });
  },

  // build the csv file for it's downloaded
  /**
   * Create the csv file and downloand it
   * @param {String} text The data text in csv format
   * @param {String} title The title of the file uploaded
   * @returns {void}
   */
  buildCsvFile(text, title){
    const blob = new Blob([text], { type: 'text/csv' });

    const url = window.URL.createObjectURL(blob);
    const aTag = document.createElement('a');
    aTag.setAttribute('href', url);
    aTag.setAttribute('download', `${title}.csv`);

    aTag.click();
    Swal.fire({
      title: 'Your Csv file has been downloaded succesfully',
      icon: 'success',
      timer: 3000,
      toast: true,
      position: 'top-right',

      showConfirmButton: false,

    });
  },

};