Fork of the excellent esp8266-react - https://github.com/rjwats/esp8266-react
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

125 lines
3.6 KiB

5 years ago
5 years ago
  1. import React from 'react';
  2. import { withSnackbar } from 'notistack';
  3. import { redirectingAuthorizedFetch } from '../authentication/Authentication';
  4. /*
  5. * It is unlikely this application will grow complex enough to require redux.
  6. *
  7. * This HOC acts as an interface to a REST service, providing data and change
  8. * event callbacks to the wrapped components along with a function to persist the
  9. * changes.
  10. */
  11. export const restComponent = (endpointUrl, FormComponent) => {
  12. return withSnackbar(
  13. class extends React.Component {
  14. constructor(props) {
  15. super(props);
  16. this.state = {
  17. data: null,
  18. fetched: false,
  19. errorMessage: null
  20. };
  21. this.setState = this.setState.bind(this);
  22. this.loadData = this.loadData.bind(this);
  23. this.saveData = this.saveData.bind(this);
  24. this.setData = this.setData.bind(this);
  25. }
  26. setData(data) {
  27. this.setState({
  28. data: data,
  29. fetched: true,
  30. errorMessage: null
  31. });
  32. }
  33. loadData() {
  34. this.setState({
  35. data: null,
  36. fetched: false,
  37. errorMessage: null
  38. });
  39. redirectingAuthorizedFetch(endpointUrl)
  40. .then(response => {
  41. if (response.status === 200) {
  42. return response.json();
  43. }
  44. throw Error("Invalid status code: " + response.status);
  45. })
  46. .then(json => { this.setState({ data: json, fetched: true }) })
  47. .catch(error => {
  48. const errorMessage = error.message || "Unknown error";
  49. this.props.enqueueSnackbar("Problem fetching: " + errorMessage, {
  50. variant: 'error',
  51. });
  52. this.setState({ data: null, fetched: true, errorMessage });
  53. });
  54. }
  55. saveData(e) {
  56. this.setState({ fetched: false });
  57. redirectingAuthorizedFetch(endpointUrl, {
  58. method: 'POST',
  59. body: JSON.stringify(this.state.data),
  60. headers: {
  61. 'Content-Type': 'application/json'
  62. }
  63. })
  64. .then(response => {
  65. if (response.status === 200) {
  66. return response.json();
  67. }
  68. throw Error("Invalid status code: " + response.status);
  69. })
  70. .then(json => {
  71. this.props.enqueueSnackbar("Changes successfully applied.", {
  72. variant: 'success',
  73. });
  74. this.setState({ data: json, fetched: true });
  75. }).catch(error => {
  76. const errorMessage = error.message || "Unknown error";
  77. this.props.enqueueSnackbar("Problem saving: " + errorMessage, {
  78. variant: 'error',
  79. });
  80. this.setState({ data: null, fetched: true, errorMessage });
  81. });
  82. }
  83. handleValueChange = name => (event) => {
  84. const { data } = this.state;
  85. data[name] = event.target.value;
  86. this.setState({ data });
  87. };
  88. handleSliderChange = name => (event, newValue) => {
  89. const { data } = this.state;
  90. data[name] = newValue;
  91. this.setState({ data });
  92. };
  93. handleCheckboxChange = name => event => {
  94. const { data } = this.state;
  95. data[name] = event.target.checked;
  96. this.setState({ data });
  97. }
  98. render() {
  99. return <FormComponent
  100. handleValueChange={this.handleValueChange}
  101. handleCheckboxChange={this.handleCheckboxChange}
  102. handleSliderChange={this.handleSliderChange}
  103. setData={this.setData}
  104. saveData={this.saveData}
  105. loadData={this.loadData}
  106. {...this.state}
  107. {...this.props}
  108. />;
  109. }
  110. }
  111. );
  112. }