Source: templates/LoaderTemplate.js

import React, { useEffect, useState } from "react";
import { connect } from "react-redux";
import { appActions } from "../../redux";
import { useSpinnerContext } from "../../_core";
import { Template } from "./Template";
import { processOptions, useReactorNavigation } from "../..";

/**
 * Componente que renderiza un template asincrónicamente, mientras espera la respuesta del servidor bloquea la pantalla con un spinner, no cuenta con la opción de auto refresco.
 * @name Reactor.Components.Templates.LoaderTemplate
 * @param {string!} href Nombre de la operación que se va a llamar
 * @param {JsonString?} data Datos que se quieran pasar a la operación
 * @param {string?} token El token permite mantener un flujo en ejecución
 * @class
 * @example
<loader_template href="HomeMovimientos" data='{"idProducto":{{idProducto}}}' token="{{token}}"/>
 */
const _LoaderTemplate = ({href, token = null, data = null, getAsyncContent}) => {

  const [ content, setContent ] = useState();
  const spinner = useSpinnerContext();
  const navigation = useReactorNavigation({target: "navigate"});
  
  useEffect(() => {
    spinner.show();
    getAsyncContent(href, token, data ? processOptions(data, null, null) : null)
      .then(response => {
        if(response.data.data.error) {
          navigation.ToError(response.data.data, true);
        }else{
          setContent(response.data.data);
        }
      })
      .catch(err => {
        navigation.ToError(err.response?.data, true);
      })  
      .finally(()=>{
        spinner.hide();
      })
  }, [href]);

  return (
    <>
        {content && 
          <Template content={content} />
        }
    </>
  )
}

export const LoaderTemplate = connect(null, appActions)(_LoaderTemplate);