Skip to content

Commit

Permalink
Merge pull request #407 from votingworks/setup-status-context
Browse files Browse the repository at this point in the history
Setup status contex
  • Loading branch information
MorganLove authored Apr 7, 2020
2 parents 7265323 + 4aa81e1 commit 5956ea8
Show file tree
Hide file tree
Showing 22 changed files with 6,941 additions and 3,850 deletions.
6 changes: 3 additions & 3 deletions arlo-client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -112,12 +112,12 @@
"jsdom": "^15.1.1",
"jspdf": "^1.5.3",
"qrcode.react": "^0.9.3",
"react": "16.9.0",
"react": "16.13.1",
"react-app-polyfill": "^1.0.1",
"react-dom": "^16.9.0",
"react-dom": "^16.13.1",
"react-router-dom": "^5.1.2",
"react-scripts": "3.4.0",
"react-test-renderer": "^16.8.6",
"react-test-renderer": "^16.13.1",
"react-toastify": "^5.3.1",
"styled-components": "^4.3.2",
"ts-node": "^8.4.1",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -269,7 +269,7 @@ exports[`Audit Setup > Contests renders empty state correctly 1`] = `
<span
class="bp3-button-text"
>
Submit & Next
Save & Next
</span>
</button>
</div>
Expand Down
19 changes: 9 additions & 10 deletions arlo-client/src/components/Audit/Setup/Contests/index.test.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import React from 'react'
import { render, fireEvent, wait } from '@testing-library/react'
import { regexpEscape } from '../../../testUtilities'
import { statusStates } from '../../_mocks'
import * as utilities from '../../../utilities'
import Contests from './index'
import relativeStages from '../_mocks'
Expand Down Expand Up @@ -100,7 +99,7 @@ describe('Audit Setup > Contests', () => {
it('renders empty state correctly', () => {
const { container } = render(
<Contests
audit={statusStates.empty}
locked={false}
isTargeted
{...relativeStages('Target Contests')}
/>
Expand All @@ -112,7 +111,7 @@ describe('Audit Setup > Contests', () => {
// skip until feature is complete in backend
const { getByText, getAllByText, queryByText } = render(
<Contests
audit={statusStates.empty}
locked={false}
isTargeted
{...relativeStages('Target Contests')}
/>
Expand Down Expand Up @@ -143,7 +142,7 @@ describe('Audit Setup > Contests', () => {
it('adds and removes choices', async () => {
const { getByText, getAllByText, queryAllByText } = render(
<Contests
audit={statusStates.empty}
locked={false}
isTargeted
{...relativeStages('Target Contests')}
/>
Expand All @@ -167,7 +166,7 @@ describe('Audit Setup > Contests', () => {
it('is able to submit the form successfully', async () => {
const { getByLabelText, getByText } = render(
<Contests
audit={statusStates.empty}
locked={false}
isTargeted
nextStage={nextStage}
prevStage={prevStage}
Expand All @@ -182,7 +181,7 @@ describe('Audit Setup > Contests', () => {
expect(input.value).toBe(inputData.value)
})

fireEvent.click(getByText('Submit & Next'), { bubbles: true })
fireEvent.click(getByText('Save & Next'), { bubbles: true })
await wait(() => {
expect(nextStage.activate).toHaveBeenCalledTimes(1)
})
Expand All @@ -191,7 +190,7 @@ describe('Audit Setup > Contests', () => {
it('displays errors', async () => {
const { getByLabelText, getByTestId, getByText } = render(
<Contests
audit={statusStates.empty}
locked={false}
isTargeted
nextStage={nextStage}
prevStage={prevStage}
Expand Down Expand Up @@ -219,7 +218,7 @@ describe('Audit Setup > Contests', () => {
}
)

fireEvent.click(getByText('Submit & Next'), { bubbles: true })
fireEvent.click(getByText('Save & Next'), { bubbles: true })
await wait(() => {
expect(nextStage.activate).toHaveBeenCalledTimes(0)
})
Expand All @@ -228,7 +227,7 @@ describe('Audit Setup > Contests', () => {
it('displays an error when the total votes are greater than the allowed votes and more than one vote is allowed per contest', async () => {
const { getByLabelText, getByTestId } = render(
<Contests
audit={statusStates.empty}
locked={false}
isTargeted
{...relativeStages('Target Contests')}
/>
Expand Down Expand Up @@ -272,7 +271,7 @@ describe('Audit Setup > Contests', () => {
it('displays no error when the total votes are greater than the ballot count, but less than the total allowed votes for a contest', async () => {
const { getByLabelText, queryByTestId } = render(
<Contests
audit={statusStates.empty}
locked={false}
isTargeted
{...relativeStages('Target Contests')}
/>
Expand Down
39 changes: 17 additions & 22 deletions arlo-client/src/components/Audit/Setup/Contests/index.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
/* eslint-disable jsx-a11y/label-has-associated-control */
import React, { useState } from 'react'
import React from 'react'
import { Formik, FormikProps, Form, Field, FieldArray } from 'formik'
import { Spinner } from '@blueprintjs/core'
import { IAudit } from '../../../../types'
import FormWrapper from '../../../Form/FormWrapper'
import FormSection, { FormSectionDescription } from '../../../Form/FormSection'
import FormField from '../../../Form/FormField'
Expand All @@ -20,10 +19,10 @@ import schema from './schema'
import { ISidebarMenuItem } from '../../../Atoms/Sidebar'

interface IProps {
audit: IAudit
isTargeted: boolean
nextStage: ISidebarMenuItem
prevStage: ISidebarMenuItem
locked: boolean
}

const contestValues: { contests: IContestValues[] } = {
Expand All @@ -50,20 +49,15 @@ const contestValues: { contests: IContestValues[] } = {

const Contests: React.FC<IProps> = ({
isTargeted,
audit,
nextStage,
prevStage,
locked,
}) => {
const [isLoading, setIsLoading] = useState(false)
const initialValues: IValues = {
contests: audit.contests.length ? audit.contests : contestValues.contests,
}
return (
<Formik
initialValues={initialValues}
initialValues={contestValues}
validationSchema={schema}
onSubmit={v => {
setIsLoading(true)
// eslint-disable-next-line no-console
console.log(v)
nextStage.activate()
Expand Down Expand Up @@ -102,7 +96,7 @@ const Contests: React.FC<IProps> = ({
<Field
id={`contests[${i}].name`}
name={`contests[${i}].name`}
disabled={audit.frozenAt}
disabled={locked}
component={FormField}
/>
</label>
Expand All @@ -114,7 +108,7 @@ const Contests: React.FC<IProps> = ({
<Field
id={`contests[${i}].numWinners`}
name={`contests[${i}].numWinners`}
disabled={audit.frozenAt}
disabled={locked}
component={FormField}
/>
</label>
Expand All @@ -127,7 +121,7 @@ const Contests: React.FC<IProps> = ({
<Field
id={`contests[${i}].votesAllowed`}
name={`contests[${i}].votesAllowed`}
disabled={audit.frozenAt}
disabled={locked}
component={FormField}
/>
</label>
Expand Down Expand Up @@ -157,20 +151,20 @@ const Contests: React.FC<IProps> = ({
Name of Candidate/Choice {j + 1}
<Field
name={`contests[${i}].choices[${j}].name`}
disabled={audit.frozenAt}
disabled={locked}
component={FlexField}
/>
</InputLabel>
<InputLabel>
Votes for Candidate/Choice {j + 1}
<Field
name={`contests[${i}].choices[${j}].numVotes`}
disabled={audit.frozenAt}
disabled={locked}
component={FlexField}
/>
</InputLabel>
{contest.choices.length > 2 &&
!audit.contests.length && (
!locked && (
<Action
onClick={() =>
choicesArrayHelpers.remove(j)
Expand All @@ -183,7 +177,7 @@ const Contests: React.FC<IProps> = ({
</React.Fragment>
)
)}
{!audit.contests.length && (
{!locked && (
<Action
onClick={() =>
choicesArrayHelpers.push({
Expand All @@ -210,7 +204,7 @@ const Contests: React.FC<IProps> = ({
<Field
id={`contests[${i}].totalBallotsCast`}
name={`contests[${i}].totalBallotsCast`}
disabled={audit.frozenAt}
disabled={locked}
component={FormField}
/>
</label>
Expand All @@ -233,17 +227,18 @@ const Contests: React.FC<IProps> = ({
)}
/>
</FormWrapper>
{isLoading && <Spinner />}
{!audit.contests.length && !isLoading && (
{nextStage.state === 'processing' ? (
<Spinner />
) : (
<FormButtonBar>
<FormButton onClick={prevStage.activate}>Back</FormButton>
<FormButton
type="submit"
intent="primary"
disabled={!!audit.frozenAt}
disabled={nextStage.state === 'locked'}
onClick={handleSubmit}
>
Submit &amp; Next
Save &amp; Next
</FormButton>
</FormButtonBar>
)}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import React from 'react'
import { fireEvent, wait } from '@testing-library/react'
import { BrowserRouter as Router, useParams } from 'react-router-dom'
import { toast } from 'react-toastify'
import { statusStates } from '../../_mocks'
import relativeStages from '../_mocks'
import Participants from './index'
import jurisdictionFile from './_mocks'
Expand Down Expand Up @@ -59,7 +58,7 @@ const fillAndSubmit = async () => {
getByTestId,
} = await asyncActRender(
<Router>
<Participants audit={statusStates.empty} nextStage={nextStage} />
<Participants locked={false} nextStage={nextStage} />
</Router>
)

Expand Down Expand Up @@ -92,7 +91,7 @@ describe('Audit Setup > Participants', () => {
it('renders empty state correctly', async () => {
const { container } = await asyncActRender(
<Router>
<Participants audit={statusStates.empty} nextStage={nextStage} />
<Participants locked={false} nextStage={nextStage} />
</Router>
)
expect(container).toMatchSnapshot()
Expand Down
23 changes: 10 additions & 13 deletions arlo-client/src/components/Audit/Setup/Participants/index.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
/* eslint-disable jsx-a11y/label-has-associated-control */
import React, { useState } from 'react'
import React from 'react'
import { Formik, FormikProps, Form, Field, ErrorMessage } from 'formik'
import { useParams } from 'react-router-dom'
import { toast } from 'react-toastify'
import styled from 'styled-components'
import { HTMLSelect, Spinner, FileInput } from '@blueprintjs/core'
import { IAudit, IErrorResponse } from '../../../../types'
import { IErrorResponse } from '../../../../types'
import FormWrapper from '../../../Form/FormWrapper'
import FormButtonBar from '../../../Form/FormButtonBar'
import FormButton from '../../../Form/FormButton'
Expand All @@ -23,17 +23,15 @@ export const Select = styled(HTMLSelect)`
`

interface IProps {
audit: IAudit
nextStage: ISidebarMenuItem
locked: boolean
}

const Participants: React.FC<IProps> = ({ audit, nextStage }: IProps) => {
const Participants: React.FC<IProps> = ({ locked, nextStage }: IProps) => {
const { electionId } = useParams()
const [isLoading, setIsLoading] = useState(false)
const [{ state }, updateSettings] = useAuditSettings(electionId!)
const submit = async (values: IValues) => {
try {
setIsLoading(true)
const responseOne = await updateSettings({ state: values.state })
if (!responseOne) return
/* istanbul ignore else */
Expand Down Expand Up @@ -82,7 +80,7 @@ const Participants: React.FC<IProps> = ({ audit, nextStage }: IProps) => {
onChange={(e: React.FormEvent<HTMLSelectElement>) =>
setFieldValue('state', e.currentTarget.value)
}
disabled={!!audit.frozenAt}
disabled={locked}
value={values.state || ''}
options={[{ value: '' }, ...labelValueStates]}
/>
Expand Down Expand Up @@ -129,16 +127,15 @@ const Participants: React.FC<IProps> = ({ audit, nextStage }: IProps) => {
)}
</FormSection>
</FormWrapper>
{isLoading && <Spinner />}
{!isLoading && (
{nextStage.state === 'processing' ? (
<Spinner />
) : (
<FormButtonBar>
<FormButton
type="submit"
intent="primary"
disabled={!!audit.frozenAt}
onClick={e => {
handleSubmit(e)
}}
disabled={nextStage.state === 'locked'}
onClick={handleSubmit}
>
Save &amp; Next
</FormButton>
Expand Down
3 changes: 1 addition & 2 deletions arlo-client/src/components/Audit/Setup/Review/index.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
import React from 'react'
import { IAudit } from '../../../../types'
import FormButtonBar from '../../../Form/FormButtonBar'
import FormButton from '../../../Form/FormButton'
import { ISidebarMenuItem } from '../../../Atoms/Sidebar'

interface IProps {
audit: IAudit
locked: boolean
prevStage: ISidebarMenuItem
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import React from 'react'
import { fireEvent, wait } from '@testing-library/react'
import { BrowserRouter as Router, useParams } from 'react-router-dom'
import { statusStates } from '../../_mocks'
import relativeStages from '../_mocks'
import Settings from './index'
import { asyncActRender, regexpEscape } from '../../../testUtilities'
Expand Down Expand Up @@ -35,11 +34,7 @@ const { nextStage, prevStage } = relativeStages('Audit Settings')
const fillAndSubmit = async () => {
const { getByText, getByLabelText, getByTestId } = await asyncActRender(
<Router>
<Settings
audit={statusStates.empty}
nextStage={nextStage}
prevStage={prevStage}
/>
<Settings locked={false} nextStage={nextStage} prevStage={prevStage} />
</Router>
)

Expand Down
Loading

0 comments on commit 5956ea8

Please sign in to comment.