All files / src/form/cells ObjectCell.tsx

80% Statements 28/35
39.28% Branches 11/28
83.33% Functions 5/6
80% Lines 28/35

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 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99                                      66x   66x       15x 15x 15x 15x 15x   15x 7x 7x     15x 9x 6x 6x 1x 1x   5x 2x 2x 2x 2x                         2x   3x 2x 2x       15x 1x     14x                                                    
import React, { ReactElement, useEffect, useState } from "react";
import { Tag, Tooltip } from "antd";
import { useTranslation } from 'react-i18next';
import { ExclamationOutlined } from '@ant-design/icons';
import { fetchCurrentValue } from "@utils/FetchUtils";
import { getObjectLabelFromCache, getLabelToDisplay, setObjectLabelToCache } from "@utils/ObjectUtils";
import ObjectPopup from "./ObjectPopup";
import { TableMode } from "@props/RecordProps";
import { emptyMethod } from "@utils/Constants";
 
interface ObjectCellRenderProps {
  domainName: string;
  id: number;
  labelField?: string;
  displayText?: string;
  tableMode?: TableMode;
  zIndex: number;
}
 
const DefaultDisplayVal = '';
 
const ObjectCell = (props: ObjectCellRenderProps): ReactElement => {
  const {
    domainName: propDomainName, id: propId, labelField, displayText,
    zIndex,
  } = props;
  const { t } = useTranslation();
  const [displayVal, setDisplayVal] = useState<string | number>(DefaultDisplayVal);
  const [hasError, setHasError] = useState<boolean>(false);
  const [errorMessage, setErrorMessage] = useState<string>();
 
  useEffect(() => {
    setDisplayVal(DefaultDisplayVal);
    setHasError(false);
  }, [propDomainName, propId]);
 
  useEffect(() => {
    if (displayText == null && propId != null) {
      const cache = getObjectLabelFromCache(propDomainName, propId);
      if (cache) {
        setHasError(false);
        setDisplayVal(cache);
      } else {
        fetchCurrentValue(propDomainName, propId).then((value) => {
          const label = getLabelToDisplay(value, labelField);
          setHasError(false);
          setDisplayVal(label);
          setObjectLabelToCache(propDomainName, propId, label);
        }).catch(exception => {
          if (exception?.status === 403 || exception?.status === 404
            || exception?.error === 404 || exception?.error === 403) {
            console.warn(`Failed to get object ${propDomainName} with id ${propId}: ${exception?.message}`);
            setHasError(true);
            if (exception.status === 403 || exception?.error === 403) {
              setErrorMessage('You do not have permission to view this object');
            }
            else if (exception.status === 404 || exception?.error === 404) {
              setErrorMessage('This object does not exist');
            }
          }
        }).finally(() => emptyMethod());
      }
    } else if (displayText != null) {
      setObjectLabelToCache(propDomainName, propId, displayText);
      setDisplayVal(displayText);
    }
  }, [displayVal, propId, propDomainName, labelField, displayText]);
 
  if (propId == null) {
    return (<></>);
  }
 
  return (
    <div className="object">
      {hasError ? (
      <Tooltip
        title={t(`Failed to load object`, {
          domainName: propDomainName, id: propId, errorMessage: t(errorMessage ?? '')
        })}>
        <Tag
          key={`${propId}`}
          className="object-id-tag"
          color="red"
          icon={<ExclamationOutlined />}
        >{propId}</Tag>
      </Tooltip>
      ) :
      <ObjectPopup
        domainName={propDomainName}
        id={propId}
        display={displayVal}
        zIndex={zIndex + 1}
      />}
    </div>
  );
};
 
export default ObjectCell;