Skip to content

Commit

Permalink
finalise new pages setup (with config)
Browse files Browse the repository at this point in the history
  • Loading branch information
natterstefan committed Jul 25, 2018
1 parent 9d851d1 commit ce1040d
Show file tree
Hide file tree
Showing 24 changed files with 204 additions and 187 deletions.
2 changes: 1 addition & 1 deletion CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
* CookieNotice component added, will be automatically present when Google Analytics
is configured
* Markdown files can be used to create content for a page (eg. a privacy page)
* breakpoints constant added
* BREAKPOINTS constant added

### Changed

Expand Down
2 changes: 1 addition & 1 deletion setup-jest.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,4 +56,4 @@ window.TrelloCards = {

// as long as we do not have implemented a Markdown-Loader for Jest, we mock
// every markdown file here
jest.mock('./src/pages-content/privacy.md', () => ({}))
jest.mock('./src/pages-content/privacy.md', () => 'Hello Privacy.md!')
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,28 @@ exports[`Component/AppMenuContainer should render proper withStyles result 1`] =
"root": "AppMenuContainer-root-1",
}
}
pages={
Array [
Object {
"component": [Function],
"icon": [Function],
"target": "/",
"title": "Dashboard",
},
Object {
"component": [Function],
"icon": [Function],
"target": "/github",
"title": "GitHub",
},
Object {
"component": [Function],
"icon": [Function],
"target": "/privacy",
"title": "Privacy",
},
]
}
theme={
Object {
"breakpoints": Object {
Expand Down Expand Up @@ -330,7 +352,30 @@ exports[`Component/AppMenuContainer should render without throwing an error 1`]
</WithStyles(IconButton)>
</div>
<WithStyles(Divider) />
<AppMenuContent />
<AppMenuContent
pages={
Array [
Object {
"component": [Function],
"icon": [Function],
"target": "/",
"title": "Dashboard",
},
Object {
"component": [Function],
"icon": [Function],
"target": "/github",
"title": "GitHub",
},
Object {
"component": [Function],
"icon": [Function],
"target": "/privacy",
"title": "Privacy",
},
]
}
/>
</WithStyles(Drawer)>
<main
className="AppMenuContainer-content-12 AppMenuContainer-content-left-13"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,34 +19,6 @@ exports[`Component/AppMenuContent should render without throwing an error 1`] =
primary="Dashboard"
/>
</WithStyles(ListItem)>
<WithStyles(ListItem)
button={true}
component={[Function]}
key="Config"
replace={true}
to="/config"
>
<WithStyles(ListItemIcon)>
<pure(Settings) />
</WithStyles(ListItemIcon)>
<WithStyles(ListItemText)
primary="Config"
/>
</WithStyles(ListItem)>
<WithStyles(ListItem)
button={true}
component={[Function]}
key="Privacy"
replace={true}
to="/privacy"
>
<WithStyles(ListItemIcon)>
<pure(Fingerprint) />
</WithStyles(ListItemIcon)>
<WithStyles(ListItemText)
primary="Privacy"
/>
</WithStyles(ListItem)>
<WithStyles(ListItem)
button={true}
component={[Function]}
Expand Down Expand Up @@ -82,6 +54,20 @@ exports[`Component/AppMenuContent should render without throwing an error 1`] =
primary="GitHub"
/>
</WithStyles(ListItem)>
<WithStyles(ListItem)
button={true}
component={[Function]}
key="Privacy"
replace={true}
to="/privacy"
>
<WithStyles(ListItemIcon)>
<pure(Fingerprint) />
</WithStyles(ListItemIcon)>
<WithStyles(ListItemText)
primary="Privacy"
/>
</WithStyles(ListItem)>
</WithStyles(List)>
</React.Fragment>
`;
5 changes: 3 additions & 2 deletions src/components/app-menu-container/__tests__/index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,14 @@ import React from 'react'
import { shallow } from 'enzyme'

import AppMenuContainer from '../'
import PAGES from '../../../pages/pages-config'

describe('Component/AppMenuContainer', () => {
const Child = () => <span>Child Content</span>

test('should render without throwing an error', () => {
const wrapper = shallow(
<AppMenuContainer>
<AppMenuContainer pages={PAGES}>
<Child />
</AppMenuContainer>,
)
Expand All @@ -18,7 +19,7 @@ describe('Component/AppMenuContainer', () => {

test('should render proper withStyles result', () => {
const wrapper = shallow(
<AppMenuContainer>
<AppMenuContainer pages={PAGES}>
<Child />
</AppMenuContainer>,
)
Expand Down
19 changes: 7 additions & 12 deletions src/components/app-menu-container/__tests__/menu.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,28 +5,29 @@ import { HashRouter as Router } from 'react-router-dom'
import ListItem from '@material-ui/core/ListItem'

import AppMenuContent from '../menu'
import PAGES from '../../../pages/pages-config'

describe('Component/AppMenuContent', () => {
test('should render without throwing an error', () => {
expect(shallow(<AppMenuContent />)).toMatchSnapshot()
expect(shallow(<AppMenuContent pages={PAGES} />)).toMatchSnapshot()
})

test('should render the proper number of ListItems', () => {
const wrapper = mount(
<Router>
<AppMenuContent />
<AppMenuContent pages={PAGES} />
</Router>,
)
expect(wrapper.find(ListItem).length).toBe(4)
expect(wrapper.find(ListItem).length).toBe(3)
})

test('should render the proper order of ListItems', () => {
const wrapper = mount(
<Router>
<AppMenuContent />
<AppMenuContent pages={PAGES} />
</Router>,
)
expect(wrapper.find(ListItem).length).toBe(4)

expect(
wrapper
.find(ListItem)
Expand All @@ -38,18 +39,12 @@ describe('Component/AppMenuContent', () => {
.find(ListItem)
.at(1)
.prop('to'),
).toBe('/config')
).toBe('/github')
expect(
wrapper
.find(ListItem)
.at(2)
.prop('to'),
).toBe('/privacy')
expect(
wrapper
.find(ListItem)
.at(3)
.prop('to'),
).toBe('/github')
})
})
9 changes: 5 additions & 4 deletions src/components/app-menu-container/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import ChevronRightIcon from '@material-ui/icons/ChevronRight'
import AppMenuContent from './menu'
import Config from '../../../config/config'

import { breakpoints } from '../../constants'
import { BREAKPOINTS } from '../../constants'

const drawerWidth = 240

Expand Down Expand Up @@ -89,7 +89,7 @@ const styles = theme => ({
'content-left': {
marginLeft: -drawerWidth,
padding: 20,
[breakpoints.small]: {
[BREAKPOINTS.small]: {
padding: 10,
},
},
Expand All @@ -109,6 +109,7 @@ class AppMenuContainer extends React.Component {
classes: PropTypes.object.isRequired, // eslint-disable-line react/forbid-prop-types
theme: PropTypes.object.isRequired, // eslint-disable-line react/forbid-prop-types
children: PropTypes.node.isRequired,
pages: PropTypes.array.isRequired, // eslint-disable-line react/forbid-prop-types
}

constructor(props) {
Expand All @@ -127,7 +128,7 @@ class AppMenuContainer extends React.Component {
}

render() {
const { classes, theme } = this.props
const { classes, theme, pages } = this.props
const { open } = this.state

const drawer = (
Expand All @@ -146,7 +147,7 @@ class AppMenuContainer extends React.Component {
</IconButton>
</div>
<Divider />
<AppMenuContent />
<AppMenuContent pages={pages} />
</Drawer>
)

Expand Down
49 changes: 6 additions & 43 deletions src/components/app-menu-container/menu.js
Original file line number Diff line number Diff line change
@@ -1,59 +1,19 @@
import React from 'react'
import PropTypes from 'prop-types'
import { map } from 'lodash'
import { Link } from 'react-router-dom'

import FontAwesomeIcon from '@fortawesome/react-fontawesome'
import List from '@material-ui/core/List'
import ListItem from '@material-ui/core/ListItem'
import ListItemIcon from '@material-ui/core/ListItemIcon'
import ListItemText from '@material-ui/core/ListItemText'
import DashboardIcon from '@material-ui/icons/Dashboard'
import SettingsIcon from '@material-ui/icons/Settings'
import FingerprintIcon from '@material-ui/icons/Fingerprint'

import Config from '../../../config/config'

let menuConfig = [
{
target: '/',
icon: () => <DashboardIcon />,
title: 'Dashboard',
},
{
target: '/config',
icon: () => <SettingsIcon />,
title: 'Config',
},
{
target: '/github',
icon: () => <FontAwesomeIcon icon={['fab', 'github']} size="lg" />,
title: 'GitHub',
},
]

// inspired by https://stackoverflow.com/a/38181008/1238150
const appendAtIndex = (array, obj, index = 0) => [
...array.slice(0, index),
obj,
...array.slice(index),
]

// - add Privacy only if config.google_analytics_property = true
if (Config.google_analytics_property) {
const menuItem = {
target: '/privacy',
icon: () => <FingerprintIcon />,
title: 'Privacy',
}
menuConfig = appendAtIndex(menuConfig, menuItem, 2)
}

// NOTE: add 'replace' property to ListItem because of:
// https://github.com/ReactTraining/react-router/issues/4467
const AppMenuContent = () => (
const AppMenuContent = props => (
<React.Fragment>
<List component="nav">
{map(menuConfig, menu => (
{map(props.pages, menu => (
<ListItem key={menu.title} component={Link} button replace to={menu.target}>
<ListItemIcon>{menu.icon()}</ListItemIcon>
<ListItemText primary={menu.title} />
Expand All @@ -64,4 +24,7 @@ const AppMenuContent = () => (
)

AppMenuContent.displayName = 'AppMenuContent'
AppMenuContent.propTypes = {
pages: PropTypes.array.isRequired, // eslint-disable-line react/forbid-prop-types
}
export default AppMenuContent
6 changes: 3 additions & 3 deletions src/constants/__tests__/constants.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { GITHUB_URL, breakpoints } from '../'
import { GITHUB_URL, BREAKPOINTS } from '../'

describe('constants', () => {
test('exports GITHUB_URL', () => {
expect(GITHUB_URL).toEqual('https://github.com/natterstefan/react-trello-multiboard/')
})

test('exports breakpoints', () => {
expect(breakpoints).toEqual({
test('exports BREAKPOINTS', () => {
expect(BREAKPOINTS).toEqual({
small: '@media (max-width: 768px)',
medium: '@media (max-width: 1440px)',
large: '@media (min-width: 1441px)',
Expand Down
2 changes: 1 addition & 1 deletion src/constants/index.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
export const GITHUB_URL = 'https://github.com/natterstefan/react-trello-multiboard/'

export const breakpoints = {
export const BREAKPOINTS = {
small: '@media (max-width: 768px)',
medium: '@media (max-width: 1440px)',
large: '@media (min-width: 1441px)',
Expand Down
10 changes: 9 additions & 1 deletion src/layout/__tests__/index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,13 @@ import CookieNotice from '../../components/cookie-notice'

describe('Layout/Layout', () => {
let wrapper
const props = {
pages: [{ target: '/some-target' }],
}

beforeEach(() => {
wrapper = shallow(
<Layout>
<Layout {...props}>
<span>SomeChild</span>
</Layout>,
)
Expand All @@ -30,4 +33,9 @@ describe('Layout/Layout', () => {
expect(wrapper.find(AppContainer)).toHaveLength(1)
expect(wrapper.find(CookieNotice)).toHaveLength(1)
})

test('should render AppContainer with the correct props', () => {
const element = wrapper.find(AppContainer)
expect(element.prop('pages')).toEqual([{ target: '/some-target' }])
})
})
3 changes: 2 additions & 1 deletion src/layout/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,13 @@ import Config from '../../config/config'
const Layout = props => (
<ErrorBoundary>
{Config.google_analytics_property && <CookieNotice />}
<AppContainer>{props.children}</AppContainer>
<AppContainer pages={props.pages}>{props.children}</AppContainer>
</ErrorBoundary>
)

Layout.displayName = 'Layout'
Layout.propTypes = {
pages: PropTypes.array.isRequired, // eslint-disable-line react/forbid-prop-types
children: PropTypes.node.isRequired,
}

Expand Down
3 changes: 3 additions & 0 deletions src/pages/__tests__/__snapshots__/page-app.test.js.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`Page/AppPage should render without throwing an error 1`] = `<Connect(WithStyles(MainApp)) />`;
Loading

0 comments on commit ce1040d

Please sign in to comment.