diff --git a/src/components/SearchListItem/index.jsx b/src/components/SearchListItem/index.jsx index 5c166fb1..74fdb71c 100644 --- a/src/components/SearchListItem/index.jsx +++ b/src/components/SearchListItem/index.jsx @@ -6,48 +6,39 @@ import TopicIcon from '../../templates/TopicIcon'; import DataIcon from '../DataIcon'; import Text from '../Text'; import { Link } from '@reach/router'; +import {countBy} from 'lodash'; + const SearchListItem = ({ className, item, }) => { const { ref, title, description, publisher, format, theme, identifier } = item; - function formats(distribution) { if (!distribution) { return null; } - if(typeof distribution === 'object') { - distribution = Object.entries(distribution); - return distribution.map((dist) => { - const type = dist[1].mediaType ? dist[1].mediaType.split('/') :''; - const backup = type ? type[1] : 'data'; - const format = (dist[1].format) ? dist[1].format : backup; - return ( -
{format} -
- ); - }) - } + if((typeof distribution === 'object') || (Array.isArray(distribution))) { + const distributionWithUniqueFormats = getUniqueFormats(Object.entries(distribution)); + const counted = countBy(distribution, (d) => { + return d.format; + }); - if(Array.isArray(distribution)) { - return distribution.map((dist) => { - const type = dist.mediaType ? dist.mediaType.split("/") : ''; - const backup = type ? type[1] : 'data'; + return distributionWithUniqueFormats.map((dist) => { + const type = dist.mediaType ? dist.mediaType.split('/') :''; + const backup = type ? type : 'data'; const format = (dist.format) ? dist.format : backup; return (
{format} + key={`dist-id-${identifier}-${Math.random() * 10}`} + className="label" + data-format={format}>{counted[format]}x {format}
); }); } - } + return null; + }; function themes(theme) { if (!theme) { @@ -114,6 +105,18 @@ const SearchListItem = ({ ); } +export const getUniqueFormats = (formats) => { + let unique = []; + return formats.reduce( + (a, b) => { + if (unique.indexOf(b[1].format) === -1) { + unique.push(b[1].format); + a.push(b[1]); + } + return a; + }, []); +}; + SearchListItem.defaultProps = { className: 'dc-search-list-item', }; diff --git a/src/components/SearchListItem/index.test.jsx b/src/components/SearchListItem/index.test.jsx index d25da205..8373ea42 100644 --- a/src/components/SearchListItem/index.test.jsx +++ b/src/components/SearchListItem/index.test.jsx @@ -1,18 +1,99 @@ import React from 'react'; import { render, screen } from '@testing-library/react'; import '@testing-library/jest-dom/extend-expect'; -import SearchListItem from './index'; +import SearchListItem, {getUniqueFormats} from './index'; describe('', () => { + test('renders an item', () => { + render(); + item={ + { + title: 'dkan', + ref: '/dkan-item', + } + } + />); expect(screen.getByRole('heading', 'Welcome to DKAN')).toBeInTheDocument(); }); + + test('Return uniquely formatted items', () => { + + const formats = [ + [0, + { + "identifier": 1, + "format": "csv" + }], + [1, + { "identifier":2, + "format": "csv" + }], + [2, + { "identifier":3, + "format": "csv" + }], + [3, + { "identifier":4, + "format": "rdf" + }], + [4, + { "identifier":5, + "format": "xml" + }] + ]; + + expect( + getUniqueFormats(formats)) + .toEqual([ + {"format": "csv", + "identifier": 1 + }, + {"format": "rdf", + "identifier": 4 + }, + {"format": "xml", + "identifier": 5 + } + ]); + }); + + test('Return formats with count.',() => { + render( + ); + + expect(screen.getByText('1x rdf')).toBeInTheDocument(); + expect(screen.getByText('1x xml')).toBeInTheDocument(); + expect(screen.getByText('3x csv')).toBeInTheDocument(); + }); });