Skip to content

Commit

Permalink
Add WorkflowMenu
Browse files Browse the repository at this point in the history
Move all the shared code for the home page workflow menu into a WorkflowMenu component. Add stories and tests.
  • Loading branch information
eatyourgreens committed Jan 14, 2021
1 parent b4e8bf9 commit 0704f21
Show file tree
Hide file tree
Showing 7 changed files with 208 additions and 68 deletions.
Original file line number Diff line number Diff line change
@@ -1,28 +1,13 @@
import { Box, Grid } from 'grommet'
import { useRouter } from 'next/router'
import React, { useState } from 'react'
import { Modal } from '@zooniverse/react-components'
import React from 'react'

import Background from '../Background'
import Introduction from '../Introduction'
import WorkflowSelector from '@shared/components/WorkflowSelector'
import { SubjectSetPicker } from '@shared/components/WorkflowSelector/components'
import WorkflowMenu from '../WorkflowMenu'
import ContentBox from '@shared/components/ContentBox'

function NarrowLayout (props) {
const { workflows } = props
const [ activeWorkflow, setActiveWorkflow ] = useState()
const router = useRouter()
const { owner, project } = router?.query || {}

function onSelectWorkflow(event, workflow) {
if (workflow.grouped) {
event.preventDefault()
setActiveWorkflow(workflow)
return false
}
return true
}

return (
<Box
Expand All @@ -38,25 +23,9 @@ function NarrowLayout (props) {
<Grid margin={{ top: 'medium-neg', horizontal: 'medium' }}>
<ContentBox gap='medium' >
<Introduction />
<WorkflowSelector
onSelect={onSelectWorkflow}
<WorkflowMenu
workflows={workflows}
/>
{activeWorkflow &&
<Modal
active
closeFn={() => setActiveWorkflow(null)}
headingBackground='brand'
title={activeWorkflow.displayName || 'Choose a subject set'}
titleColor='neutral-6'
>
<SubjectSetPicker
owner={owner}
project={project}
workflow={activeWorkflow}
/>
</Modal>
}
</ContentBox>
</Grid>
</Box>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,10 @@
import { Box } from 'grommet'
import { useRouter } from 'next/router'
import React, { useState } from 'react'
import React from 'react'
import styled from 'styled-components'
import { Modal } from '@zooniverse/react-components'

import Background from '../Background'
import Introduction from '../Introduction'
import WorkflowSelector from '@shared/components/WorkflowSelector'
import { SubjectSetPicker } from '@shared/components/WorkflowSelector/components'
import WorkflowMenu from '../WorkflowMenu'
import ContentBox from '@shared/components/ContentBox'

const GrowBox = styled(Box)`
Expand All @@ -20,18 +17,6 @@ const StyledContentBox = styled(ContentBox)`

function WideLayout (props) {
const { workflows } = props
const [ activeWorkflow, setActiveWorkflow ] = useState()
const router = useRouter()
const { owner, project } = router?.query || {}

function onSelectWorkflow(event, workflow) {
if (workflow.grouped) {
event.preventDefault()
setActiveWorkflow(workflow)
return false
}
return true
}

return (
<GrowBox align='stretch' direction='row' justify='between'>
Expand All @@ -45,25 +30,9 @@ function WideLayout (props) {
width='38%'
>
<Introduction />
<WorkflowSelector
onSelect={onSelectWorkflow}
<WorkflowMenu
workflows={workflows}
/>
{activeWorkflow &&
<Modal
active
closeFn={() => setActiveWorkflow(null)}
headingBackground='brand'
title={activeWorkflow.displayName || 'Choose a subject set'}
titleColor='neutral-6'
>
<SubjectSetPicker
owner={owner}
project={project}
workflow={activeWorkflow}
/>
</Modal>
}
</StyledContentBox>
</GrowBox>
)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import asyncStates from '@zooniverse/async-states'
import zooTheme from '@zooniverse/grommet-theme'
import { Grommet } from 'grommet'
import { Provider } from 'mobx-react'
import { mockWorkflow as mockGroupedWorkflow } from '@shared/components/WorkflowSelector/components/SubjectSetPicker/helpers'
import WorkflowMenu from './WorkflowMenu'

const store = {
project: {
background: {
src: 'https://panoptes-uploads.zooniverse.org/production/project_background/260e68fd-d3ec-4a94-bb32-43ff91d5579a.jpeg'
},
description: 'Learn about and help document the wonders of nesting Western Bluebirds.',
display_name: 'Nest Quest Go: Western Bluebirds',
slug: 'brbcornell/nest-quest-go-western-bluebirds',
workflow_description: `Choose your own adventure! There are many ways to engage with this project:
1) "Nest Site": Smartphone-friendly, helps us understand where Western Bluebirds build their nests.
2) "Location": Smartphone-friendly, series of questions on the geographic location of the nest.
3) "Nest Attempt: Smartphone-friendly, for data-entry lovers to record nest attempt data on cards.
4) "Comments": For transcription lovers, we ask you to transcribe all the written comments on the cards.`
},
user: {
loadingState: asyncStates.success
}
}

const WORKFLOWS = [
{
completeness: 0.65,
default: false,
displayName: 'The Family and the Fishing Net',
id: '12345'
},
{
completeness: 0,
default: false,
displayName: 'Games Without Frontiers',
id: '7890'
},
{
completeness: 0.99,
default: false,
displayName: 'Shock The Monkey',
id: '5678'
}
]

function StoryContext (props) {
const { children, theme } = props

return (
<Grommet
background={{
dark: 'dark-1',
light: 'light-1'
}}
theme={theme}
themeMode={(theme.dark) ? 'dark' : 'light'}
>
<Provider store={store}>
{children}
</Provider>
</Grommet>
)
}

export default {
title: 'Project App / Screens / Project Home / Workflow Menu',
component: WorkflowMenu,
args: {
dark: false,
workflows: [ ...WORKFLOWS, mockGroupedWorkflow ]
}
}

export function Default({ dark, workflows }) {
return (
<StoryContext theme={{ ...zooTheme, dark }}>
<WorkflowMenu workflows={workflows} />
</StoryContext>
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import { arrayOf, shape, string } from 'prop-types'
import { useRouter } from 'next/router'
import React, { useState } from 'react'
import { Modal } from '@zooniverse/react-components'

import WorkflowSelector from '@shared/components/WorkflowSelector'
import { SubjectSetPicker } from '@shared/components/WorkflowSelector/components'

export default function WorkflowMenu({ workflows }) {
const [ activeWorkflow, setActiveWorkflow ] = useState()
const router = useRouter()
const { owner, project } = router?.query || {}

function onSelectWorkflow(event, workflow) {
if (workflow.grouped) {
event.preventDefault()
setActiveWorkflow(workflow)
return false
}
return true
}
return (
<>
<WorkflowSelector
onSelect={onSelectWorkflow}
workflows={workflows}
/>
{activeWorkflow &&
<Modal
active
closeFn={() => setActiveWorkflow(null)}
headingBackground='brand'
title={activeWorkflow.displayName || 'Choose a subject set'}
titleColor='neutral-6'
>
<SubjectSetPicker
owner={owner}
project={project}
workflow={activeWorkflow}
/>
</Modal>
}
</>
)
}

WorkflowMenu.defaultProps = {
workflows: []
}

WorkflowMenu.propTypes = {
workflows: arrayOf(shape({
id: string.isRequired
}))
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import { shallow } from 'enzyme'
import sinon from 'sinon'
import WorkflowSelector from '@shared/components/WorkflowSelector'
import { SubjectSetPicker } from '@shared/components/WorkflowSelector/components'

import WorkflowMenu from './WorkflowMenu'

describe('Component > Hero > WorkflowMenu', function () {
let wrapper

const WORKFLOWS = [
{
completeness: 0.65,
default: false,
displayName: 'The Family and the Fishing Net',
grouped: true,
id: '12345'
},
{
completeness: 0,
default: false,
displayName: 'Games Without Frontiers',
id: '7890'
},
{
completeness: 0.99,
default: false,
displayName: 'Shock The Monkey',
id: '5678'
}
]

beforeEach(function () {
wrapper = shallow(<WorkflowMenu workflows={WORKFLOWS} />)
})

it('should show a workflow selector', function () {
expect(wrapper.find(WorkflowSelector)).to.have.lengthOf(1)
})

describe('on selecting', function () {
let onSelect

beforeEach(function () {
onSelect = wrapper.find(WorkflowSelector).prop('onSelect')
})

describe('a grouped workflow', function () {
it('should show a subject set picker', function () {
onSelect( { preventDefault: sinon.stub() }, WORKFLOWS[0])
expect(wrapper.find(SubjectSetPicker)).to.have.lengthOf(1)
})
})

describe('an ordinary workflow', function () {
it('should not show a subject set picker', function () {
onSelect( { preventDefault: sinon.stub() }, WORKFLOWS[1])
expect(wrapper.find(SubjectSetPicker)).to.have.lengthOf(0)
})
})
})
})
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default } from './WorkflowMenu'
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,9 @@ const subjectSets = [
]

const WORKFLOW = {
completeness: 0.34,
displayName: 'Question Workflow (grouped)',
grouped: true,
id: '15652',
subjectSets
}
Expand Down

0 comments on commit 0704f21

Please sign in to comment.