Source: templates/ToggleVariable.js

  1. import React, { useContext, useEffect, useRef, useState } from "react";
  2. import { useDispatch, useSelector } from "react-redux";
  3. import { processOptions, FormContext } from "../..";
  4. import { appActions } from "../../redux";
  5. const safeEval = require('safe-eval-2')
  6. /**
  7. * Componente que responde al evento click
  8. * @name Reactor.Components.Templates.ToggleVariable
  9. * @param {string!} variable Nombre de la variable
  10. * @param {string} [context = "global"] Nombre del contexto a usar
  11. * @param {(string|JsonString)} on Valor cuando esta on (puede ser json string para setear un objeto en la variable)
  12. * @param {(string|JsonString)} off Valor cuando esta off (puede ser json string para setear un objeto en la variable)
  13. * @param {BooleanString} [prevent_default = "true"] True para cortar evitar que el evento click se envie a los componente hijos
  14. * @param {JsonString} options Json string con los atributos que se quieran enviar al div contenedor
  15. * @param {("on"|"off")} [default_state = "off"] Estado por default del componente (setea la variable al renderizarse)
  16. * @param {BooleanString} [use_event = "false"] Indica si se envia un evento al form que lo contiene
  17. * @class
  18. * @example
  19. <toggle_variable
  20. variable="type_password"
  21. on="text" off="password"
  22. context="login"
  23. prevent_default="true"
  24. default_state="off"
  25. use_event="false"
  26. >
  27. ...
  28. <toggle_variable/>
  29. */
  30. export const ToggleVariable = ({variable, context = "global", on, off, prevent_default = "true", children, options, default_state = "off", use_event = "false"}) => {
  31. const dispatch = useDispatch();
  32. const varsContext = useSelector(state => state.app.variables)
  33. const [state, setState] = useState()
  34. useEffect(()=>{
  35. const newState = default_state === "on" ? "on" : "off";
  36. const finalData = getOnOff(on, off, newState, varsContext)
  37. setState(newState);
  38. if( varsContext ){
  39. dispatch(appActions.setVariable(variable, finalData, context));
  40. }
  41. }, [on, off, default_state]);
  42. const handleClick = (event) => {
  43. if(prevent_default === "true"){
  44. event.preventDefault()
  45. }
  46. const newState = state === "on" ? "off" : "on";
  47. const finalData = getOnOff(on, off, newState, varsContext)
  48. if( varsContext ){
  49. dispatch(appActions.setVariable(variable, finalData, context));
  50. }
  51. setState(newState);
  52. }
  53. return <div onClick={handleClick} {...processOptions(options)}>{children}</div>;
  54. }
  55. const getOnOff = (on, off, state, context) => {
  56. return dataEval(
  57. state === "on"
  58. ? processOptions(on, on, on)
  59. : processOptions(off, off, off)
  60. , context
  61. );
  62. }
  63. const dataEval = (data, varsContext) => {
  64. if (typeof data !== "string") return data;
  65. const newData = data.startsWith("ev|")
  66. ? safeEval(data.substring(3))
  67. : data;
  68. const finalData = typeof newData === "function"
  69. ? newData(varsContext, document)
  70. : newData;
  71. return finalData;
  72. }