Skip to content

Commit

Permalink
Merge pull request #32 from folio-org/UIMARCAUTH-20
Browse files Browse the repository at this point in the history
UIMARCAUTH-20: Implement Results List Column Chooser
  • Loading branch information
Vladyslav-Velytskyi authored Dec 9, 2021
2 parents 50b686b + 31cda7c commit 563c51e
Show file tree
Hide file tree
Showing 8 changed files with 144 additions and 14 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@
* [UIMARCAUTH-6](https://issues.folio.org/browse/UIMARCAUTH-6) Add View MARC authority record permission.
* [UIMARCAUTH-5](https://issues.folio.org/browse/UIMARCAUTH-5) Add Edit MARC authority record permission.
* [UIMARCAUTH-16](https://issues.folio.org/browse/UIMARCAUTH-16) Implement MARC Authorities Search Box.
* [UIMARCAUTH-20](https://issues.folio.org/browse/UIMARCAUTH-20) Implement Results List Column Chooser.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
"inflected": "^2.0.4",
"jest": "^26.6.3",
"jest-junit": "^12.0.0",
"lodash": "^4.17.4",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react-intl": "^5.8.0",
Expand Down
14 changes: 3 additions & 11 deletions src/components/SearchResultsList/SearchResultsList.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,29 +4,26 @@ import { FormattedMessage } from 'react-intl';
import { MultiColumnList } from '@folio/stripes/components';

import { AuthorityShape } from '../../constants/shapes';
import { searchResultListColumns } from '../../constants';

const propTypes = {
authorities: PropTypes.arrayOf(AuthorityShape).isRequired,
loading: PropTypes.bool,
onNeedMoreData: PropTypes.func.isRequired,
pageSize: PropTypes.number.isRequired,
totalResults: PropTypes.number,
visibleColumns: PropTypes.arrayOf(PropTypes.string).isRequired,
};

const authRef = 'Auth/Ref';

const searchResultListColumns = {
AUTH_REF_TYPE: 'authRefType',
HEADING_REF: 'headingRef',
HEADING_TYPE: 'headingType',
};

const SearchResultsList = ({
authorities,
totalResults,
loading,
pageSize,
onNeedMoreData,
visibleColumns,
}) => {
const columnMapping = {
[searchResultListColumns.AUTH_REF_TYPE]: <FormattedMessage id="ui-marc-authorities.search-results-list.authRefType" />,
Expand All @@ -45,11 +42,6 @@ const SearchResultsList = ({
: authority.authRefType;
},
};
const visibleColumns = [
searchResultListColumns.AUTH_REF_TYPE,
searchResultListColumns.HEADING_REF,
searchResultListColumns.HEADING_TYPE,
];

return (
<MultiColumnList
Expand Down
29 changes: 29 additions & 0 deletions src/components/SearchResultsList/SearchResultsList.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,17 @@ import noop from 'lodash/noop';
import Harness from '../../../test/jest/helpers/harness';
import SearchResultsList from './SearchResultsList';
import authorities from '../../../mocks/authorities.json';
import { searchResultListColumns } from '../../constants';

const renderSearchResultsList = (props = {}) => render(
<Harness>
<SearchResultsList
authorities={authorities}
visibleColumns={[
searchResultListColumns.AUTH_REF_TYPE,
searchResultListColumns.HEADING_REF,
searchResultListColumns.HEADING_TYPE,
]}
totalResults={authorities.length}
loading={false}
pageSize={15}
Expand All @@ -26,4 +32,27 @@ describe('Given SearchResultsList', () => {

expect(getAllByText('Twain, Mark')).toHaveLength(15);
});

it('should display 3 columns', () => {
const { getByText } = renderSearchResultsList();

expect(getByText('ui-marc-authorities.search-results-list.authRefType')).toBeDefined();
expect(getByText('ui-marc-authorities.search-results-list.headingRef')).toBeDefined();
expect(getByText('ui-marc-authorities.search-results-list.headingType')).toBeDefined();
});

describe('when show columns checkbox for "Type of Heading" is not checked', () => {
it('should display 2 columns', () => {
const { queryByText } = renderSearchResultsList({
visibleColumns: [
searchResultListColumns.AUTH_REF_TYPE,
searchResultListColumns.HEADING_REF,
],
});

expect(queryByText('ui-marc-authorities.search-results-list.authRefType')).toBeDefined();
expect(queryByText('ui-marc-authorities.search-results-list.headingRef')).toBeDefined();
expect(queryByText('ui-marc-authorities.search-results-list.headingType')).toBeNull();
});
});
});
1 change: 1 addition & 0 deletions src/constants/index.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export * from './searchableIndexesValues';
export * from './rawSearchableIndexes';
export * from './searchableIndexesMap';
export * from './searchResultsListColumns';
5 changes: 5 additions & 0 deletions src/constants/searchResultsListColumns.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export const searchResultListColumns = {
AUTH_REF_TYPE: 'authRefType',
HEADING_REF: 'headingRef',
HEADING_TYPE: 'headingType',
};
38 changes: 36 additions & 2 deletions src/views/AuthoritiesSearch/AuthoritiesSearch.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,10 @@ import {
useHistory,
useLocation,
} from 'react-router-dom';
import { useIntl } from 'react-intl';
import {
FormattedMessage,
useIntl,
} from 'react-intl';
import queryString from 'query-string';
import {
useLocalStorage,
Expand All @@ -24,6 +27,8 @@ import {
CollapseFilterPaneButton,
ExpandFilterPaneButton,
PersistedPaneset,
useColumnManager,
ColumnManagerMenu,
} from '@folio/stripes/smart-components';

import {
Expand All @@ -36,10 +41,15 @@ import {
SearchResultsList,
} from '../../components';
import { useAuthorities } from '../../hooks/useAuthorities';
import { rawSearchableIndexes } from '../../constants';
import {
rawSearchableIndexes,
searchResultListColumns,
} from '../../constants';

import css from './AuthoritiesSearch.css';

const prefix = 'authorities';

const AuthoritiesSearch = () => {
const intl = useIntl();
const [, getNamespace] = useNamespace();
Expand All @@ -55,6 +65,16 @@ const AuthoritiesSearch = () => {
const [searchDropdownValue, setSearchDropdownValue] = useState('');
const [searchIndex, setSearchIndex] = useState('');

const columnMapping = {
[searchResultListColumns.AUTH_REF_TYPE]: <FormattedMessage id="ui-marc-authorities.search-results-list.authRefType" />,
[searchResultListColumns.HEADING_REF]: <FormattedMessage id="ui-marc-authorities.search-results-list.headingRef" />,
[searchResultListColumns.HEADING_TYPE]: <FormattedMessage id="ui-marc-authorities.search-results-list.headingType" />,
};
const {
visibleColumns,
toggleColumn,
} = useColumnManager(prefix, columnMapping);

useEffect(() => {
const locationSearchParams = queryString.parse(location.search);

Expand Down Expand Up @@ -121,6 +141,18 @@ const AuthoritiesSearch = () => {
);
};

const renderActionMenu = () => {
return (
<ColumnManagerMenu
prefix={prefix}
visibleColumns={visibleColumns}
toggleColumn={toggleColumn}
columnMapping={columnMapping}
excludeColumns={[searchResultListColumns.HEADING_REF]}
/>
);
};

const searchableIndexes = rawSearchableIndexes.map(index => ({
label: intl.formatMessage({ id: index.label }),
value: index.value,
Expand Down Expand Up @@ -189,12 +221,14 @@ const AuthoritiesSearch = () => {
defaultWidth="fill"
paneTitle={intl.formatMessage({ id: 'ui-marc-authorities.meta.title' })}
firstMenu={renderResultsFirstMenu()}
actionMenu={renderActionMenu}
>
<SearchResultsList
authorities={authorities}
totalResults={totalRecords}
pageSize={pageSize}
onNeedMoreData={onFetchNextPage}
visibleColumns={visibleColumns}
/>
</Pane>
</PersistedPaneset>
Expand Down
69 changes: 68 additions & 1 deletion src/views/AuthoritiesSearch/AuthoritiesSearch.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
fireEvent,
} from '@testing-library/react';

import mockMapValues from 'lodash/mapValues';
import routeData from 'react-router';

import { createMemoryHistory } from 'history';
Expand All @@ -13,7 +14,10 @@ import '../../../test/jest/__mock__';

import Harness from '../../../test/jest/helpers/harness';
import AuthoritiesSearch from './AuthoritiesSearch';
import { searchableIndexesValues } from '../../constants';
import {
searchableIndexesValues,
searchResultListColumns,
} from '../../constants';

const history = createMemoryHistory();
const historyReplaceSpy = jest.spyOn(history, 'replace');
Expand All @@ -22,6 +26,15 @@ jest.mock('../../hooks/useAuthorities', () => ({
useAuthorities: () => ({ authorities: [] }),
}));

jest.mock('../../components', () => ({
...jest.requireActual('../../components'),
SearchResultsList: (props) => {
const mapedProps = mockMapValues(props, (prop) => ((typeof prop === 'object') ? JSON.stringify(prop) : prop));

return (<div data-testid="SearchResultsList" {...mapedProps} />);
},
}));

const renderAuthoritiesSearch = (props = {}) => render(
<Harness history={history}>
<AuthoritiesSearch {...props} />
Expand Down Expand Up @@ -67,6 +80,12 @@ describe('Given AuthoritiesSearch', () => {
expect(getByRole('button', { name: 'stripes-smart-components.resetAll' })).toBeDefined();
});

it('display "Action" button', () => {
const { getByRole } = renderAuthoritiesSearch();

expect(getByRole('button', { name: 'stripes-components.paneMenuActionsToggleLabel' })).toBeDefined();
});

describe('when textarea is not empty and Reset all button is clicked', () => {
it('should clear textarea', () => {
const {
Expand Down Expand Up @@ -178,4 +197,52 @@ describe('Given AuthoritiesSearch', () => {
});
});
});

describe('when click on "Action" button', () => {
it('should display "Show columns" section', () => {
const {
getByRole,
getByText,
} = renderAuthoritiesSearch();

fireEvent.click(getByRole('button', { name: 'stripes-components.paneMenuActionsToggleLabel' }));

expect(getByText('stripes-smart-components.columnManager.showColumns')).toBeDefined();
});

it('should display "Authorized/Reference" and "Type of heading" checkboxes', () => {
const { getByRole } = renderAuthoritiesSearch();

fireEvent.click(getByRole('button', { name: 'stripes-components.paneMenuActionsToggleLabel' }));

expect(getByRole('checkbox', { name: 'ui-marc-authorities.search-results-list.authRefType' })).toBeDefined();
expect(getByRole('checkbox', { name: 'ui-marc-authorities.search-results-list.headingType' })).toBeDefined();
});

it('should be checked by the default', () => {
const { getByRole } = renderAuthoritiesSearch();

fireEvent.click(getByRole('button', { name: 'stripes-components.paneMenuActionsToggleLabel' }));

expect(getByRole('checkbox', { name: 'ui-marc-authorities.search-results-list.authRefType' })).toBeChecked();
expect(getByRole('checkbox', { name: 'ui-marc-authorities.search-results-list.headingType' })).toBeChecked();
});

describe('when click on "Type of Heading" checkbox', () => {
it('should hide "Type of Heading" column', () => {
const {
getByRole,
getByTestId,
} = renderAuthoritiesSearch();

fireEvent.click(getByRole('button', { name: 'stripes-components.paneMenuActionsToggleLabel' }));
fireEvent.click(getByRole('checkbox', { name: 'ui-marc-authorities.search-results-list.headingType' }));

expect(getByTestId('SearchResultsList')).toHaveAttribute('visibleColumns', JSON.stringify([
searchResultListColumns.AUTH_REF_TYPE,
searchResultListColumns.HEADING_REF,
]));
});
});
});
});

0 comments on commit 563c51e

Please sign in to comment.