All files / RefdataButtons RefdataButtons.js

66.66% Statements 20/30
60% Branches 9/15
71.42% Functions 5/7
68.96% Lines 20/29

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 100          27x   4x 4x     4x   4x   4x 4x 4x   12x                 12x                     4x 4x 8x     8x 8x       4x 4x 4x                                                   4x               27x                            
import React from 'react';
import PropTypes from 'prop-types';
import { useIntl } from 'react-intl';
import { Col, RadioButton, Row } from '@folio/stripes/components';
 
const RefdataButtons = (props) => {
  // Render the right number of buttons:
  const { labelTranslations, lockColumns, maxCols = 4 } = props;
  const intl = useIntl();
 
  // maxCols can be any of 1,2,3 or 4. Anything outside of this should be disregarded and default to 4.
  const maximumColumns = [1, 2, 3, 4].includes(maxCols) ? maxCols : 4;
 
  const buttonRender = (dataOptions, dynamicColumnWidth) => {
    // This accepts a SORTED list of dataoptions.
    const { input } = props;
    const numberOfButtons = dataOptions.length;
    return (
      dataOptions.map(option => {
        const buttonProps = {
          'checked': input.value === option.value,
          'fullWidth': true,
          'label': (labelTranslations ? intl.formatMessage({ id: `${labelTranslations.key}.${option.value}`, defaultMessage: option.label }) : option.label),
          'marginBottom0': true,
          'onChange': (() => input.onChange(option.value)),
          'value': option.value
        };
 
        return (
          <Col key={`${input.name}:${option.id}`} xs={dynamicColumnWidth ? (12 / numberOfButtons) : (12 / maximumColumns)}>
            <RadioButton
              {...buttonProps}
            />
          </Col>
        );
      })
    );
  };
 
  const returnRows = (dataOptions) => {
    const sortedDataOptions = dataOptions.sort((a, b) => {
      Iif (a.label < b.label) {
        return -1;
      }
      Eif (a.label > b.label) {
        return 1;
      }
      return 0;
    });
    const arrayLength = sortedDataOptions.length;
    Eif (!lockColumns && arrayLength <= maximumColumns) {
      return (
        <Row>
          {buttonRender(sortedDataOptions, true)}
        </Row>
      );
    }
 
    const rowsNeeded = Math.ceil(sortedDataOptions.length / maximumColumns);
    const chunkedDataOptions = [];
 
    for (let i = 0; i < rowsNeeded; i++) {
      chunkedDataOptions.push(sortedDataOptions.slice((i * maximumColumns), (i * maximumColumns + maximumColumns)));
    }
    return (
      chunkedDataOptions.map((cdo, index) => {
        return (
          <Row
            key={`${props.input.name}:row${index}`}
          >
            {buttonRender(cdo, false)}
          </Row>
        );
      })
    );
  };
 
  return (
    <>
      {props.label}
      {returnRows(props.dataOptions)}
    </>
  );
};
 
RefdataButtons.propTypes = {
  dataOptions: PropTypes.arrayOf(PropTypes.shape({
    id: PropTypes.string.isRequired,
    label: PropTypes.string.isRequired,
    value: PropTypes.string.isRequired,
  })),
  input: PropTypes.shape({
    value: PropTypes.string.isRequired,
    onChange: PropTypes.func.isRequired,
  }).isRequired,
  label: PropTypes.oneOfType([PropTypes.string, PropTypes.node]),
};
 
export default RefdataButtons;