From 0d92942deccf8a0521efa6da636c7e53d17adbaf Mon Sep 17 00:00:00 2001 From: Jessie Keck <jessie.keck@gmail.com> Date: Tue, 19 Mar 2019 15:37:31 -0700 Subject: [PATCH] Add an AnnotationSettings component to be rendered in the Annotation panel. --- .../src/components/AnnotationSettings.test.js | 78 +++++++++++++++++++ src/components/AnnotationSettings.js | 42 ++++++++++ src/containers/AnnotationSettings.js | 39 ++++++++++ src/locales/en/translation.json | 1 + 4 files changed, 160 insertions(+) create mode 100644 __tests__/src/components/AnnotationSettings.test.js create mode 100644 src/components/AnnotationSettings.js create mode 100644 src/containers/AnnotationSettings.js diff --git a/__tests__/src/components/AnnotationSettings.test.js b/__tests__/src/components/AnnotationSettings.test.js new file mode 100644 index 000000000..259453fc1 --- /dev/null +++ b/__tests__/src/components/AnnotationSettings.test.js @@ -0,0 +1,78 @@ +import React from 'react'; +import { shallow } from 'enzyme'; +import { AnnotationSettings } from '../../../src/components/AnnotationSettings'; + +/** */ +function createWrapper(props) { + return shallow( + <AnnotationSettings + displayAll={false} + displayAllDisabled={false} + t={k => k} + toggleAnnotationDisplay={() => {}} + windowId="abc123" + {...props} + />, + ); +} + +describe('AnnotationSettings', () => { + let control; + let wrapper; + const toggleAnnotationDisplayMock = jest.fn(); + + + it('renders a FormControlLabel and a Switch', () => { + wrapper = createWrapper(); + control = shallow( + wrapper.find('WithStyles(WithFormControlContext(FormControlLabel))').props().control, + ); + expect(wrapper.find('WithStyles(WithFormControlContext(FormControlLabel))').length).toBe(1); + expect(control.find('Switch').length).toBe(1); + }); + + describe('control', () => { + it('is not checked when the displayAll prop is false', () => { + wrapper = createWrapper(); + control = shallow( + wrapper.find('WithStyles(WithFormControlContext(FormControlLabel))').props().control, + ); + + expect(control.find('Switch').props().checked).toBe(false); + }); + + it('is checked when the displayAll prop is true', () => { + wrapper = createWrapper({ displayAll: true }); + control = shallow( + wrapper.find('WithStyles(WithFormControlContext(FormControlLabel))').props().control, + ); + + expect(control.find('Switch').props().checked).toBe(true); + }); + + it('is disabled based on the displayAllDisabled prop', () => { + wrapper = createWrapper(); + control = shallow( + wrapper.find('WithStyles(WithFormControlContext(FormControlLabel))').props().control, + ); + expect(control.find('Switch').props().disabled).toBe(false); + + wrapper = createWrapper({ displayAllDisabled: true }); + control = shallow( + wrapper.find('WithStyles(WithFormControlContext(FormControlLabel))').props().control, + ); + expect(control.find('Switch').props().disabled).toBe(true); + }); + + it('calls the toggleAnnotationDisplay prop function on change', () => { + wrapper = createWrapper({ toggleAnnotationDisplay: toggleAnnotationDisplayMock }); + control = shallow( + wrapper.find('WithStyles(WithFormControlContext(FormControlLabel))').props().control, + ); + + control.find('Switch').props().onChange(); // trigger the onChange prop + + expect(toggleAnnotationDisplayMock).toHaveBeenCalledTimes(1); + }); + }); +}); diff --git a/src/components/AnnotationSettings.js b/src/components/AnnotationSettings.js new file mode 100644 index 000000000..6d8313cc4 --- /dev/null +++ b/src/components/AnnotationSettings.js @@ -0,0 +1,42 @@ +import React, { Component } from 'react'; +import PropTypes from 'prop-types'; +import FormControlLabel from '@material-ui/core/FormControlLabel'; +import Switch from '@material-ui/core/Switch'; + +/** + * AnnotationSettings is a component to handle various annotation + * display settings in the Annotation companion window +*/ +export class AnnotationSettings extends Component { + /** + * Returns the rendered component + */ + render() { + const { + displayAll, displayAllDisabled, t, toggleAnnotationDisplay, + } = this.props; + + return ( + <FormControlLabel + control={( + <Switch + checked={displayAll} + disabled={displayAllDisabled} + onChange={toggleAnnotationDisplay} + value={displayAll ? 'all' : 'select'} + /> + )} + label={t('displayAllAnnotations')} + labelPlacement="start" + /> + ); + } +} + +AnnotationSettings.propTypes = { + displayAll: PropTypes.bool.isRequired, + displayAllDisabled: PropTypes.bool.isRequired, + t: PropTypes.func.isRequired, + toggleAnnotationDisplay: PropTypes.func.isRequired, + windowId: PropTypes.string.isRequired, // eslint-disable-line react/no-unused-prop-types +}; diff --git a/src/containers/AnnotationSettings.js b/src/containers/AnnotationSettings.js new file mode 100644 index 000000000..5fbec40b2 --- /dev/null +++ b/src/containers/AnnotationSettings.js @@ -0,0 +1,39 @@ +import { compose } from 'redux'; +import { connect } from 'react-redux'; +import { withTranslation } from 'react-i18next'; +import * as actions from '../state/actions'; +import { withPlugins } from '../extend'; +import { + getAnnotationResourcesByMotivation, + getSelectedTargetAnnotations, + getSelectedCanvas, +} from '../state/selectors'; +import { AnnotationSettings } from '../components/AnnotationSettings'; + +/** + * Mapping redux state to component props using connect + */ +const mapStateToProps = (state, { windowId }) => ({ + displayAll: state.windows[windowId].displayAllAnnotations, + displayAllDisabled: getAnnotationResourcesByMotivation( + getSelectedTargetAnnotations(state, (getSelectedCanvas(state, { windowId }) || {}).id), + ['oa:commenting', 'sc:painting'], + ).length < 2, +}); + +/** + * Mapping redux action dispatches to component props using connect + */ +const mapDispatchToProps = (dispatch, { windowId }) => ({ + toggleAnnotationDisplay: () => { + dispatch(actions.toggleAnnotationDisplay(windowId)); + }, +}); + +const enhance = compose( + withTranslation(), + connect(mapStateToProps, mapDispatchToProps), + withPlugins('AnnotationSettings'), +); + +export default enhance(AnnotationSettings); diff --git a/src/locales/en/translation.json b/src/locales/en/translation.json index 2aa1e49e4..ceac6cbdc 100644 --- a/src/locales/en/translation.json +++ b/src/locales/en/translation.json @@ -18,6 +18,7 @@ "currentItem": "Current item", "dark": "Dark theme", "dismiss": "Dismiss", + "displayAllAnnotations": "Highlight all", "downloadExport": "Download/Export workspace", "downloadExportWorkspace": "Download/Export workspace", "elastic": "Elastic", -- GitLab