All files / client/src/components ErrorBar.tsx

91.66% Statements 11/12
100% Branches 4/4
100% Functions 4/4
90.9% Lines 10/11

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48                520x 642x 642x   2400x   642x 617x     25x       31x             31x               1x                    
import { ReactElement } from "react";
import { useTranslation } from "react-i18next";
import { DismissibleBanner } from "client/components/DismissibleBanner";
import { HighlightStyle } from "client/components/componentStyles";
import { BackendErrorType } from "client/types/errorTypes";
import { useAppDispatch, useAppSelector } from "client/utils/hooks";
import { removeError } from "client/views/admin/adminSlice";
 
export const ErrorBar = (): ReactElement | null => {
  const { t } = useTranslation();
  const dispatch = useAppDispatch();
 
  const errors = useAppSelector((state) => state.admin.errors);
 
  if (errors.length === 0) {
    return null;
  }
 
  const errorList = errors.map((error) => {
    // Errors are stored as translation keys so removal matching survives
    // language switches; translate here at render time
    const message =
      error.errorKey === BackendErrorType.API_ERROR
        ? t(error.errorKey, {
            method: error.method,
            url: error.url,
            errorReason: t(error.errorReason),
          })
        : t(error.errorKey);
    return (
      <DismissibleBanner
        key={message}
        data-testid="error-bar-item"
        icon="triangle-exclamation"
        highlightStyle={HighlightStyle.WARN}
        dismissAriaLabel={t("iconAltText.closeError")}
        onDismiss={() => {
          dispatch(removeError(error));
        }}
      >
        <span>{message}</span>
      </DismissibleBanner>
    );
  });
 
  return <div>{errorList}</div>;
};