Passed
Push — dev ( b490d9...5daa38 )
by Tristan
04:45 queued 10s
created

resources/assets/js/components/ErrorToast.tsx   A

Complexity

Total Complexity 2
Complexity/F 0

Size

Lines of Code 95
Function Count 0

Duplication

Duplicated Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
wmc 2
eloc 77
mnd 2
bc 2
fnc 0
dl 0
loc 95
rs 10
bpm 0
cpm 0
noi 0
c 0
b 0
f 0
1
import React, { useEffect } from "react";
2
import { connect } from "react-redux";
3
import {
4
  injectIntl,
5
  FormattedMessage,
6
  WrappedComponentProps,
7
} from "react-intl";
8
import { ApiError } from "redux-api-middleware";
9
import { ErrorEntity } from "../store/Error/errorReducer";
10
import { clearErrors } from "../store/Error/errorActions";
11
import { getRecentError } from "../store/Error/errorSelector";
12
import { RootState } from "../store/store";
13
import { DispatchType } from "../configureStore";
14
15
const constructErrorMessage = (error: ErrorEntity): string => {
16
  if (error.error instanceof ApiError) {
17
    // if error was of type redux-api-middleware/ApiError, we may be able to extract extra info from the response.
18
    const apiError = error.error;
19
    if (apiError.status && apiError.response && apiError.response.message) {
20
      return `${apiError.status} - ${apiError.response.message}`;
21
    }
22
  }
23
  return error.message;
24
};
25
interface ErrorToastProps {
26
  error: ErrorEntity;
27
  dispatchClearErrors: () => void;
28
}
29
const ErrorToast: React.FC<ErrorToastProps & WrappedComponentProps> = ({
30
  error,
31
  dispatchClearErrors,
32
}): React.ReactElement => {
33
  useEffect((): (() => void) => {
34
    const timer = setInterval((): void => {
35
      dispatchClearErrors();
36
      clearInterval(timer);
37
    }, 3500);
38
    return (): void => {
39
      clearInterval(timer);
40
    };
41
  }, [dispatchClearErrors, error]);
42
43
  return (
44
    <>
45
      {error !== undefined && (
46
        <div data-c-alert="error(toast)" data-c-radius="rounded" role="alert">
47
          <div data-c-padding="half">
48
            <span data-c-margin="bottom(quarter)" data-c-font-weight="bold">
49
              <FormattedMessage
50
                id="errorToast.title"
51
                defaultMessage="Something went wrong!"
52
                description="Title displayed on the Error Toast component."
53
              />
54
            </span>
55
            <p>{constructErrorMessage(error)}</p>
56
          </div>
57
          <button
58
            type="button"
59
            onClick={(): void => {
60
              dispatchClearErrors();
61
            }}
62
            data-c-alert="close-trigger"
63
            data-c-padding="half"
64
          >
65
            <i className="fa fa-times-circle" />
66
          </button>
67
        </div>
68
      )}
69
    </>
70
  );
71
};
72
73
const mapStateToProps = (
74
  state: RootState,
75
): {
76
  error: ErrorEntity;
77
} => ({
78
  error: getRecentError(state),
79
});
80
81
const mapDispatchToProps = (
82
  dispatch: DispatchType,
83
): { dispatchClearErrors: () => void } => ({
84
  dispatchClearErrors: (): void => {
85
    dispatch(clearErrors());
86
  },
87
});
88
89
const ErrorToastContainer = connect(
90
  mapStateToProps,
91
  mapDispatchToProps,
92
)(injectIntl(ErrorToast));
93
94
export default ErrorToastContainer;
95