huridocs/uwazi

View on GitHub
app/react/App/RouteHandler.js

Summary

Maintainability
A
0 mins
Test Coverage
A
95%
/** @format */

import { I18NUtils } from 'app/I18N';
import { isClient } from 'app/utils';
import api from 'app/utils/api';
import { RequestParams } from 'app/utils/RequestParams';
import moment from 'moment';
import PropTypes from 'prop-types';
import React, { Component } from 'react';

const getLocale = ({ store }) => store.getState().locale;

const setLocale = locale => {
  moment.locale(locale);
  api.locale(locale);
  I18NUtils.saveLocale(locale);
};

class RouteHandler extends Component {
  static async requestState(_requestParams, _state) {
    return new Promise((resolve, _reject) => {
      resolve([]);
    });
  }

  emptyState() {} //eslint-disable-line

  //eslint-disable-next-line
  isRenderedFromServer() {
    const result = RouteHandler.renderedFromServer;
    RouteHandler.renderedFromServer = false;
    return result;
  }

  constructor(props, context) {
    super(props, context);
    setLocale(getLocale(context));
    this.state = {};
    if ((!this.isRenderedFromServer() || props.location?.state?.isClient) && isClient) {
      this.getClientState(this.props).catch(ex => {
        // used in inherited types
        // eslint-disable-next-line react/no-unused-state
        this.setState({ loadingError: ex });
      });
    }
  }

  componentDidUpdate(prevProps) {
    if (this.urlHasChanged(prevProps)) {
      this.emptyState();
      this.getClientState(this.props);
    }
  }

  async getClientState(props) {
    let query;
    const { lang, ...routeParams } = props.params;
    if (props.location) {
      const params = new URLSearchParams(props.location.search);
      query = Object.fromEntries(params.entries());
    }

    const { store = { getState: () => {} } } = this.context;

    const headers = {};
    const requestParams = new RequestParams({ ...query, ...routeParams }, headers);
    const actions = await this.constructor.requestState(requestParams, store.getState());

    actions.forEach(action => {
      store.dispatch(action);
    });
  }

  urlHasChanged(prevProps) {
    const { params: nextParams = {}, matches: nextRoutes = [] } = prevProps;
    const { params, matches: routes } = this.props;

    const sameParams = Object.keys(nextParams).reduce(
      (memo, key) => memo && prevProps.params[key] === params[key],
      true
    );
    const sameAmountOfparams = Object.keys(nextParams).length === Object.keys(params).length;
    const currentPath = routes.reduce((path, r) => path + r.path, '');
    const newPath = nextRoutes.reduce((path, r) => path + r.path, '');
    const samePath = currentPath === newPath;
    return !sameParams || !sameAmountOfparams || !samePath;
  }

  render() {
    return <div>{false}</div>;
  }
}

RouteHandler.renderedFromServer = true;

RouteHandler.defaultProps = {
  params: {},
};

RouteHandler.contextTypes = {
  getInitialData: PropTypes.func,
  isRenderedFromServer: PropTypes.func,
  router: PropTypes.object,
  store: PropTypes.object,
};

RouteHandler.propTypes = {
  params: PropTypes.object,
  routes: PropTypes.array,
  location: PropTypes.object,
  matches: PropTypes.array,
};

export default RouteHandler;