From 656160d30a3cd4ff0d816904f193e66a7c5a1045 Mon Sep 17 00:00:00 2001
From: Chris Beer <cabeer@stanford.edu>
Date: Thu, 31 Jan 2019 11:49:56 -0800
Subject: [PATCH] Add a WindowThumbnailSettings control to the window's menu

---
 .../WindowThumbnailSettings.test.js           | 27 +++++++
 src/components/WindowThumbnailSettings.js     | 71 +++++++++++++++++++
 src/components/WindowTopMenu.js               |  5 ++
 src/containers/WindowThumbnailSettings.js     | 29 ++++++++
 4 files changed, 132 insertions(+)
 create mode 100644 __tests__/src/components/WindowThumbnailSettings.test.js
 create mode 100644 src/components/WindowThumbnailSettings.js
 create mode 100644 src/containers/WindowThumbnailSettings.js

diff --git a/__tests__/src/components/WindowThumbnailSettings.test.js b/__tests__/src/components/WindowThumbnailSettings.test.js
new file mode 100644
index 000000000..6453d313c
--- /dev/null
+++ b/__tests__/src/components/WindowThumbnailSettings.test.js
@@ -0,0 +1,27 @@
+import React from 'react';
+import { shallow } from 'enzyme';
+import WindowThumbnailSettings from '../../../src/components/WindowThumbnailSettings';
+
+describe('WindowThumbnailSettings', () => {
+  let wrapper;
+  const setWindowThumbnailPosition = jest.fn();
+  beforeEach(() => {
+    wrapper = shallow(
+      <WindowThumbnailSettings
+        windowId="xyz"
+        setWindowThumbnailPosition={setWindowThumbnailPosition}
+        thumbnailNavigationPosition="bottom"
+      />,
+    );
+  });
+
+  it('renders without an error', () => {
+    expect(wrapper.find('WithStyles(Typography)').dive().dive().text()).toBe('Thumbnails');
+    expect(wrapper.find('RadioGroup').props().value).toBe('bottom');
+  });
+
+  it('updates state when the thumbnail config selection changes', () => {
+    wrapper.find('RadioGroup').first().simulate('change', { target: { value: 'off' } });
+    expect(setWindowThumbnailPosition).toHaveBeenCalledWith('xyz', 'off');
+  });
+});
diff --git a/src/components/WindowThumbnailSettings.js b/src/components/WindowThumbnailSettings.js
new file mode 100644
index 000000000..5f49d4ff3
--- /dev/null
+++ b/src/components/WindowThumbnailSettings.js
@@ -0,0 +1,71 @@
+import React, { Component } from 'react';
+import FormControlLabel from '@material-ui/core/FormControlLabel';
+import Radio from '@material-ui/core/Radio';
+import RadioGroup from '@material-ui/core/RadioGroup';
+import Typography from '@material-ui/core/Typography';
+import PropTypes from 'prop-types';
+
+/**
+ *
+ */
+export default class WindowThumbnailSettings extends Component {
+  /**
+   * constructor -
+   */
+  constructor(props) {
+    super(props);
+    this.state = {
+    };
+    this.handleChange = this.handleChange.bind(this);
+  }
+
+  /**
+   * @private
+   */
+  handleChange(event) {
+    const { windowId, setWindowThumbnailPosition } = this.props;
+
+    setWindowThumbnailPosition(windowId, event.target.value);
+  }
+
+  /**
+   * render
+   *
+   * @return {type}  description
+   */
+  render() {
+    const { thumbnailNavigationPosition } = this.props;
+
+    return (
+      <>
+        <Typography>Thumbnails</Typography>
+        <RadioGroup aria-label="position" name="position" value={thumbnailNavigationPosition} onChange={this.handleChange} row>
+          <FormControlLabel
+            value="off"
+            control={<Radio color="primary" />}
+            label="Off"
+            labelPlacement="bottom"
+          />
+          <FormControlLabel
+            value="bottom"
+            control={<Radio color="primary" />}
+            label="Bottom"
+            labelPlacement="bottom"
+          />
+          <FormControlLabel
+            value="right"
+            control={<Radio color="primary" />}
+            label="Right"
+            labelPlacement="bottom"
+          />
+        </RadioGroup>
+      </>
+    );
+  }
+}
+
+WindowThumbnailSettings.propTypes = {
+  windowId: PropTypes.string.isRequired,
+  setWindowThumbnailPosition: PropTypes.func.isRequired,
+  thumbnailNavigationPosition: PropTypes.string.isRequired,
+};
diff --git a/src/components/WindowTopMenu.js b/src/components/WindowTopMenu.js
index 15aa2c458..a7e41a2f8 100644
--- a/src/components/WindowTopMenu.js
+++ b/src/components/WindowTopMenu.js
@@ -1,9 +1,11 @@
 import React, { Component } from 'react';
 import { compose } from 'redux';
+import ListItem from '@material-ui/core/ListItem';
 import Menu from '@material-ui/core/Menu';
 import Divider from '@material-ui/core/Divider';
 import { withStyles } from '@material-ui/core/styles';
 import PropTypes from 'prop-types';
+import WindowThumbnailSettings from '../containers/WindowThumbnailSettings';
 
 /**
  */
@@ -28,6 +30,9 @@ class WindowTopMenu extends Component {
     return (
       <>
         <Menu id={`window-menu_${windowId}`} anchorEl={anchorEl} open={Boolean(anchorEl)} onClose={handleClose}>
+          <ListItem>
+            <WindowThumbnailSettings windowId={windowId} />
+          </ListItem>
           <Divider />
         </Menu>
       </>
diff --git a/src/containers/WindowThumbnailSettings.js b/src/containers/WindowThumbnailSettings.js
new file mode 100644
index 000000000..75b0e9472
--- /dev/null
+++ b/src/containers/WindowThumbnailSettings.js
@@ -0,0 +1,29 @@
+import { compose } from 'redux';
+import { connect } from 'react-redux';
+import * as actions from '../state/actions';
+import WindowThumbnailSettings from '../components/WindowThumbnailSettings';
+
+/**
+ * mapDispatchToProps - used to hook up connect to action creators
+ * @memberof ManifestListItem
+ * @private
+ */
+const mapDispatchToProps = { setWindowThumbnailPosition: actions.setWindowThumbnailPosition };
+
+/**
+ * mapStateToProps - to hook up connect
+ * @memberof WindowViewer
+ * @private
+ */
+const mapStateToProps = (state, props) => (
+  {
+    thumbnailNavigationPosition: state.windows[props.windowId].thumbnailNavigationPosition,
+  }
+);
+
+const enhance = compose(
+  connect(mapStateToProps, mapDispatchToProps),
+  // further HOC go here
+);
+
+export default enhance(WindowThumbnailSettings);
-- 
GitLab