diff --git a/__tests__/src/components/App.test.js b/__tests__/src/components/App.test.js index 77bf22bb5c09ced33816758d39402a94461d8371..049550d337b924f4ba6b26f8cc44113faa1def0d 100644 --- a/__tests__/src/components/App.test.js +++ b/__tests__/src/components/App.test.js @@ -4,13 +4,25 @@ import App from '../../../src/components/App'; describe('App', () => { it('renders without an error', () => { - const wrapper = shallow(<App manifests={[]} workspace={{}} />); + const wrapper = shallow( + <App + manifests={[]} + workspace={{}} + config={{ theme: 'light' }} + />, + ); expect(wrapper.find('div.mirador-app').length).toBe(1); }); describe('FullScreen', () => { - it('is enabled by the workspace.isFullscreenEnabled state', () => { - const wrapper = shallow(<App manifests={[]} workspace={{ isFullscreenEnabled: true }} />); + it('is enabled by the workspace.fullscreen state', () => { + const wrapper = shallow( + <App + manifests={[]} + workspace={{ isFullscreenEnabled: true }} + config={{ theme: 'light' }} + />, + ); expect(wrapper.find('FullScreen').first().prop('enabled')).toEqual(true); }); }); diff --git a/__tests__/src/components/WorkspaceSettings.test.js b/__tests__/src/components/WorkspaceSettings.test.js index 339cc3425280627ddddd2205106bd039c9827d8d..9a265c0565b4bb680890af68e1b890a5734bdf35 100644 --- a/__tests__/src/components/WorkspaceSettings.test.js +++ b/__tests__/src/components/WorkspaceSettings.test.js @@ -5,19 +5,28 @@ import WorkspaceSettings from '../../../src/components/WorkspaceSettings'; describe('WorkspaceSettings', () => { let wrapper; let handleClose; + let updateConfig; beforeEach(() => { handleClose = jest.fn(); + updateConfig = jest.fn(); wrapper = shallow( <WorkspaceSettings open handleClose={handleClose} + updateConfig={updateConfig} + theme="light" />, ); }); it('renders without an error', () => { expect(wrapper.find('WithStyles(Dialog)').length).toBe(1); + expect(wrapper.find('WithStyles(FormControl)').length).toBe(1); + }); + it('calls updateConfig when selected', () => { + wrapper.instance().handleThemeChange({ target: { value: 'foo' } }); + expect(updateConfig).toHaveBeenCalled(); }); }); diff --git a/src/components/WorkspaceMenu.js b/src/components/WorkspaceMenu.js index 3b8b74a215e2907070ea19c1c0a3c8a901489bb9..bcb016dab8b2d5372b2d0925a270edb1daf4dd57 100644 --- a/src/components/WorkspaceMenu.js +++ b/src/components/WorkspaceMenu.js @@ -9,7 +9,7 @@ import SettingsIcon from '@material-ui/icons/Settings'; import ViewHeadlineIcon from '@material-ui/icons/ViewHeadline'; import PropTypes from 'prop-types'; import WindowList from '../containers/WindowList'; -import WorkspaceSettings from './WorkspaceSettings'; +import WorkspaceSettings from '../containers/WorkspaceSettings'; import WorkspaceExport from '../containers/WorkspaceExport'; /** diff --git a/src/components/WorkspaceSettings.js b/src/components/WorkspaceSettings.js index 55aa12ffd23a5e5752d52b27869fec297a7f0231..fbd7c3f2c8f3c35a2c3f2eac1451571b84ca31a2 100644 --- a/src/components/WorkspaceSettings.js +++ b/src/components/WorkspaceSettings.js @@ -2,24 +2,59 @@ import React, { Component } from 'react'; import Dialog from '@material-ui/core/Dialog'; import DialogContent from '@material-ui/core/DialogContent'; import DialogTitle from '@material-ui/core/DialogTitle'; +import FormControl from '@material-ui/core/FormControl'; +import InputLabel from '@material-ui/core/InputLabel'; +import Select from '@material-ui/core/Select'; +import MenuItem from '@material-ui/core/MenuItem'; import PropTypes from 'prop-types'; /** */ class WorkspaceSettings extends Component { + /** + * constructor - + */ + constructor(props) { + super(props); + this.handleThemeChange = this.handleThemeChange.bind(this); + } + + /** + * Propagate theme selection into the global state + */ + handleThemeChange(event) { + const { updateConfig } = this.props; + + updateConfig({ theme: event.target.value }); + } + /** * render * @return */ render() { const { - handleClose, open, children, + handleClose, open, children, theme, } = this.props; return ( <Dialog id="workspace-settings" open={open} onClose={handleClose}> <DialogTitle id="form-dialog-title">Settings</DialogTitle> <DialogContent> {children} + <FormControl> + <InputLabel htmlFor="theme-simple">Theme</InputLabel> + <Select + value={theme} + onChange={this.handleThemeChange} + inputProps={{ + name: 'theme', + id: 'theme-simple', + }} + > + <MenuItem value="light">Light</MenuItem> + <MenuItem value="dark">Dark</MenuItem> + </Select> + </FormControl> </DialogContent> </Dialog> ); @@ -30,6 +65,8 @@ WorkspaceSettings.propTypes = { handleClose: PropTypes.func.isRequired, open: PropTypes.bool, // eslint-disable-line react/forbid-prop-types children: PropTypes.node, + updateConfig: PropTypes.func.isRequired, + theme: PropTypes.string.isRequired, }; WorkspaceSettings.defaultProps = { diff --git a/src/containers/WorkspaceSettings.js b/src/containers/WorkspaceSettings.js new file mode 100644 index 0000000000000000000000000000000000000000..a52b463006165a812e01d231e9144683fc600838 --- /dev/null +++ b/src/containers/WorkspaceSettings.js @@ -0,0 +1,31 @@ +import { compose } from 'redux'; +import { connect } from 'react-redux'; +import WorkspaceSettings from '../components/WorkspaceSettings'; +import * as actions from '../state/actions'; + +/** + * mapDispatchToProps - used to hook up connect to action creators + * @memberof ManifestListItem + * @private + */ +const mapDispatchToProps = { + updateConfig: actions.updateConfig, +}; + +/** + * mapStateToProps - to hook up connect + * @memberof Workspace + * @private + */ +const mapStateToProps = state => ( + { + theme: state.config.theme, + } +); + +const enhance = compose( + connect(mapStateToProps, mapDispatchToProps), + // further HOC go here +); + +export default enhance(WorkspaceSettings);