From 431c6e1cc2c89b583afb81c479e5c648e0ca4041 Mon Sep 17 00:00:00 2001 From: Chris Beer <cabeer@stanford.edu> Date: Tue, 5 Feb 2019 07:01:01 -0800 Subject: [PATCH] Add the manifest's logo to the window top bar; fixes #1794 --- __tests__/src/components/WindowIcon.test.js | 41 +++++++++++++++++ __tests__/src/components/WindowTopBar.test.js | 4 ++ src/components/WindowIcon.js | 46 +++++++++++++++++++ src/components/WindowTopBar.js | 4 +- 4 files changed, 94 insertions(+), 1 deletion(-) create mode 100644 __tests__/src/components/WindowIcon.test.js create mode 100644 src/components/WindowIcon.js diff --git a/__tests__/src/components/WindowIcon.test.js b/__tests__/src/components/WindowIcon.test.js new file mode 100644 index 000000000..d5a209d73 --- /dev/null +++ b/__tests__/src/components/WindowIcon.test.js @@ -0,0 +1,41 @@ +import React from 'react'; +import { shallow } from 'enzyme'; +import WindowIcon from '../../../src/components/WindowIcon'; + +describe('WindowIcon', () => { + let wrapper; + let manifestation; + + describe('without a manifestation', () => { + beforeEach(() => { + wrapper = shallow(<WindowIcon />).dive(); + }); + + it('renders without an error', () => { + expect(wrapper.find('img').length).toBe(0); + }); + }); + + + describe('with a manifestation without a logo', () => { + beforeEach(() => { + manifestation = { getLogo: () => null }; + wrapper = shallow(<WindowIcon manifestation={manifestation} />).dive(); + }); + + it('renders without an error', () => { + expect(wrapper.find('img').length).toBe(0); + }); + }); + + describe('with a manifestation with a logo', () => { + beforeEach(() => { + manifestation = { getLogo: () => 'http://example.com/thumbnail.jpg' }; + wrapper = shallow(<WindowIcon manifestation={manifestation} classes={{ logo: 'logo-class' }} />).dive(); + }); + + it('renders without an error', () => { + expect(wrapper.find('img.logo-class[src="http://example.com/thumbnail.jpg"]').length).toBe(1); + }); + }); +}); diff --git a/__tests__/src/components/WindowTopBar.test.js b/__tests__/src/components/WindowTopBar.test.js index 0246fa5dc..250249f37 100644 --- a/__tests__/src/components/WindowTopBar.test.js +++ b/__tests__/src/components/WindowTopBar.test.js @@ -36,6 +36,10 @@ describe('WindowTopBar', () => { .toBe(mockRemoveWindow); }); + it('renders a window icon', () => { + expect(topBar.find('WithStyles(WindowIcon)').length).toBe(1); + }); + it('calls the toggleWindowSideBar prop when the menu IconButton is clicked', () => { topBar.find('WithStyles(IconButton)').simulate('click'); expect(mockToggleWindowSideBar).toHaveBeenCalledTimes(1); diff --git a/src/components/WindowIcon.js b/src/components/WindowIcon.js new file mode 100644 index 000000000..28a4edf95 --- /dev/null +++ b/src/components/WindowIcon.js @@ -0,0 +1,46 @@ +import React, { Component } from 'react'; +import PropTypes from 'prop-types'; +import { withStyles } from '@material-ui/core/styles'; + +/** + */ +class WindowIcon extends Component { + /** + * render + * @return + */ + render() { + const { + manifestation, classes, + } = this.props; + + if (manifestation && manifestation.getLogo()) { + return (<img src={manifestation.getLogo()} alt="" role="presentation" className={classes.logo} />); + } + + return ( + <></> + ); + } +} + +WindowIcon.propTypes = { + manifestation: PropTypes.shape({ + getLogo: PropTypes.func, + }), + classes: PropTypes.shape({ logo: PropTypes.string }), +}; + +WindowIcon.defaultProps = { + manifestation: null, + classes: {}, +}; + +const styles = { + logo: { + height: '2.5rem', + paddingRight: 8, + }, +}; + +export default withStyles(styles)(WindowIcon); diff --git a/src/components/WindowTopBar.js b/src/components/WindowTopBar.js index a5f61fdb2..23c9b07dd 100644 --- a/src/components/WindowTopBar.js +++ b/src/components/WindowTopBar.js @@ -7,6 +7,7 @@ import IconButton from '@material-ui/core/IconButton'; import MenuIcon from '@material-ui/icons/Menu'; import Toolbar from '@material-ui/core/Toolbar'; import classNames from 'classnames'; +import WindowIcon from './WindowIcon'; import WindowTopMenuButton from './WindowTopMenuButton'; import WindowTopBarButtons from '../containers/WindowTopBarButtons'; import ns from '../config/css-ns'; @@ -34,7 +35,7 @@ class WindowTopBar extends Component { */ render() { const { - removeWindow, windowId, classes, toggleWindowSideBar, + removeWindow, windowId, classes, toggleWindowSideBar, manifest, } = this.props; return ( <Toolbar disableGutters className={classNames(classes.reallyDense, ns('window-top-bar'))} variant="dense"> @@ -45,6 +46,7 @@ class WindowTopBar extends Component { > <MenuIcon /> </IconButton> + <WindowIcon manifestation={manifest.manifestation} /> <Typography variant="h3" noWrap color="inherit" className={classes.typographyBody}> {this.titleContent()} </Typography> -- GitLab