containers/Settings/OddsTemplatesFile.js

import React, { Component } from 'react';
import { connect } from 'react-redux';
import {
  aGetPermissions,
  aGetOddsTemplatesFiles,
  aGetDownloadTemplatesFile,
  aGetUploadTemplatesFile,
} from '../../reducers/actions';
import { ODDS_TEMPLATES_FILES_TXT, PERMISSIONS } from '../../constants';
import { getOddsTemplatesFiles, getDownloadedOddsTemplatesFile } from '../../selectors/settings';
import { checkPermisson, isFetched, isLastRecord, hasRecord, getSelectedTimezone } from '../../selectors/common';
import { getCountryDateTime } from '../../utils/common';
import ScrollTable from '../../components/ScrollTable';
import TableNoResult from '../../components/TableNoResult';

const mapToProps = (state) => ({
  oddsTemplateFiles: getOddsTemplatesFiles(state),
  downloadedFile: getDownloadedOddsTemplatesFile(state),
  checkPermisson: (payload) => checkPermisson(state, payload),
  isFetched: isFetched(state),
  isLastRecord: isLastRecord(state),
  hasRecord: hasRecord(state),
  selectedTimezone: getSelectedTimezone(state),
});

const actionsToProps = (dispatch) => ({
  getOddsTemplateFiles: (payload) => dispatch(aGetOddsTemplatesFiles(payload)),
  getDownloadOddsTemplatesFile: (payload) => dispatch(aGetDownloadTemplatesFile(payload)),
  getUploadOddsTemplateFile: (payload) => dispatch(aGetUploadTemplatesFile(payload)),
  getPermissions: (payload) => dispatch(aGetPermissions(payload)),
});

/**
 * @class
 * @property {object} props
 * @property {Array} props.oddsTemplateFiles Odds Templates files data
 * @property {boolean} props.checkPermisson
 * @property {Function} props.getOddsTemplateFiles Call API for odds templates files
 * @property {Function} props.getUploadOddsTemplateFile Call API to upload template file
 * @property {Function} props.getDownloadOddsTemplatesFile Call API to download template file
 *
 */
class OddsTemplatesFile extends Component {
  constructor(props) {
    super(props);
    this.state = {
      inputLabel: ODDS_TEMPLATES_FILES_TXT.inputLabel,
      isError: false,
    };
    /**
     * @member {object}
     * @description Check of user have permission for some of actions
     * @property {boolean} view
     * @property {boolean} upload
     * @property {boolean} download
     */
    this.hasPermissionTo = {
      view: props.checkPermisson(PERMISSIONS.ODDS_TEMPLATE_FILES_VIEW),
      upload: props.checkPermisson(PERMISSIONS.ODDS_TEMPLATE_FILES_UPLOAD),
      download: props.checkPermisson(PERMISSIONS.ODDS_TEMPLATE_FILES_DOWNLOAD),
    };
  }

  /**
   * Get initial data
   *
   * @returns {void}
   */
  componentDidMount() {
    this.refreshTable();
    this.props.getPermissions();
  }

  /**
   * on component update download document
   *
   * @param {object} prevProps
   * @returns {void}
   */
  componentDidUpdate(prevProps) {
    if (prevProps.downloadedFile !== this.props.downloadedFile) {
      window.location.assign(this.props.downloadedFile.url);
    }
  }

  /**
   * Refresh and update odds templates files table
   *
   * @function
   * @returns {void}
   */
  refreshTable = () => {
    this.props.getOddsTemplateFiles();
  };

  /**
   * Upload odds template file
   *
   * @function
   * @returns {void}
   */
  uploadOddsTemplateFile = () => {
    this.props.getUploadOddsTemplateFile(this.fileUpload.files[0]);
    this.fileUpload.value = '';
    this.setState({ inputLabel: ODDS_TEMPLATES_FILES_TXT.inputLabel });
  };

  /**
   * download odds templates file
   *
   * @function
   * @param {object} file
   * @param {object} e
   * @returns {void}
   */
  /* eslint-disable no-unused-vars */
  downloadFile = (file, e) => {
    this.props.getDownloadOddsTemplatesFile(file);
  };

  /**
   * Render odds templates files rows
   *
   * @function
   * @param {object} oddFile
   * @param {object} key
   * @returns {view}
   */
  renderOddsTemplatesFilesRows = (oddFile, key) => (
    <tr className="table-style-row" key={key}>
      <td>{oddFile.fileName}</td>
      <td>{getCountryDateTime(oddFile.inDt, this.props.selectedTimezone)}</td>
      <td>{oddFile.inUser}</td>
      <td>
        {this.hasPermissionTo.download && (
          <button
            id={`file-${oddFile.fileName}`}
            type="button"
            className="btn btn-primary"
            key={oddFile}
            onClick={this.downloadFile.bind(this, oddFile.fileName)}
          >
            Download
          </button>
        )}
      </td>
    </tr>
  );

  /**
   * put correct label after change input
   *
   * @function
   * @returns {void}
   */
  onChangeInputFile = () => {
    const newTxt =
      this.fileUpload && this.fileUpload.files.length > 0
        ? `${`${this.fileUpload.files[0].name}`}`
        : ODDS_TEMPLATES_FILES_TXT.inputLabel;
    const extention = newTxt.substring(newTxt.lastIndexOf('.') + 1, newTxt.length);
    if (extention === ODDS_TEMPLATES_FILES_TXT.validExtention) {
      this.setState({
        inputLabel: newTxt,
        isError: false,
      });
    } else {
      this.setState({
        inputLabel: ODDS_TEMPLATES_FILES_TXT.inputLabel,
        isError: true,
      });
    }
  };

  /**
   * Render error mgs
   *
   * @returns {view}
   */
  renderErrorMgs() {
    return <div className="error-txt mt-2">{ODDS_TEMPLATES_FILES_TXT.inputErrorMgs}</div>;
  }

  /**
   * Render
   *
   * @returns {view}
   */
  render() {
    return (
      this.hasPermissionTo.view && (
        <div className="user">
          <ScrollTable
            loadMore={this.refreshTable}
            isFetched={this.props.isFetched}
            isLastRecord={this.props.isLastRecord}
          >
            <>
              <table className="table-style table-s">
                <thead>
                  <tr>
                    <th>Name</th>
                    <th>Date</th>
                    <th>User</th>
                    <th>Download</th>
                  </tr>
                </thead>
                <tbody>
                  {this.props.oddsTemplateFiles.map((oddFile, key) => this.renderOddsTemplatesFilesRows(oddFile, key))}
                </tbody>
              </table>
              {!this.props.hasRecord && !this.props.oddsTemplateFiles.length && <TableNoResult />}
            </>
          </ScrollTable>
          <div className="user__settings mt-20">
            <div className="row">
              {this.hasPermissionTo.upload && (
                <div className="col-sm-12 d-flex align-items-center">
                  <p className="m-0">Upload new file (*File accepted: xlsx)</p>
                  <div className="ml-30">
                    <input
                      type="file"
                      className="d-none"
                      id="file"
                      name="file"
                      ref={(ref) => {
                        this.fileUpload = ref;
                      }}
                      onChange={this.onChangeInputFile}
                    />
                    <label htmlFor="file" className="m-0">
                      <div className="file-btn">{this.state.inputLabel}</div>
                    </label>
                  </div>
                  <button
                    id="oddsTemplatesFile_UploadBtn"
                    className="btn btn-primary ml-30"
                    onClick={this.uploadOddsTemplateFile}
                    type="button"
                    disabled={(this.fileUpload && this.fileUpload.files.length < 1) || this.state.isError === true}
                  >
                    Upload
                  </button>
                </div>
              )}
            </div>
            {this.state.isError && this.renderErrorMgs()}
          </div>
          <div className="user__info mt-20">*Uploaded files will be displayed in the table(s) above</div>
        </div>
      )
    );
  }
}

export default connect(mapToProps, actionsToProps)(OddsTemplatesFile);