Skip to content

Commit

Permalink
feat(protocol-designer): step edit form opens on edit button
Browse files Browse the repository at this point in the history
closes AUTH-879
  • Loading branch information
jerader committed Sep 29, 2024
1 parent 983b1cf commit 86b4df9
Show file tree
Hide file tree
Showing 9 changed files with 128 additions and 115 deletions.
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
{
"add_details": "Add step details",
"delete": "Delete step",
"duplicate": "Duplicate step",
"edit_step": "Edit step",
"final_deck_state": "Final deck state",
"new_location": "New location",
"protocol_steps": "Protocol steps",
"protocol_timeline": "Protocol timeline",
"rename": "Rename step",
"select_labware": "Select labware",
"starting_deck_state": "Starting deck state",
"view_commands": "View commands"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,39 +65,24 @@ export function ConnectedStepInfo(props: ConnectedStepInfoProps): JSX.Element {
const unhighlightStep = (): HoverOnStepAction =>
dispatch(stepsActions.hoverOnStep(null))

// const { confirm, showConfirmation, cancel } = useConditionalConfirm(
// handleStepItemSelection,
// currentFormIsPresaved || singleEditFormHasUnsavedChanges
// )

const iconName = stepIconsByType[step.stepType]

return (
<>
{/* {showConfirmation && (
<ConfirmDeleteModal
modalType={getModalType()}
onContinueClick={confirm}
onCancelClick={cancel}
/>
)} */}
<StepContainer
hasError={hasError}
isStepAfterError={stepAfterError}
stepId={stepId}
onMouseLeave={unhighlightStep}
selected={selected}
// setSelectedStep={setSelectedStep}
onClick={() => {
selectStep()
}}
hovered={hoveredStep === stepId && !hoveredSubstep}
onMouseEnter={highlightStep}
iconName={hasError || hasWarnings ? 'alert-circle' : iconName}
title={`${stepNumber}. ${
step.stepName || t(`stepType.${step.stepType}`)
}`}
/>
</>
<StepContainer
hasError={hasError}
isStepAfterError={stepAfterError}
stepId={stepId}
onMouseLeave={unhighlightStep}
selected={selected}
onClick={() => {
selectStep()
}}
hovered={hoveredStep === stepId && !hoveredSubstep}
onMouseEnter={highlightStep}
iconName={hasError || hasWarnings ? 'alert-circle' : iconName}
title={`${stepNumber}. ${
step.stepName || t(`stepType.${step.stepType}`)
}`}
/>
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ export function StepContainer(props: StepContainerProps): JSX.Element {
setStepOverflowMenu(false)
}
}
console.log(formData)

return (
<>
<Box
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import type * as React from 'react'
import { useTranslation } from 'react-i18next'
import styled from 'styled-components'
import { useDispatch } from 'react-redux'
import { useDispatch, useSelector } from 'react-redux'

import {
ALIGN_CENTER,
Expand All @@ -13,14 +12,25 @@ import {
NO_WRAP,
POSITION_ABSOLUTE,
SPACING,
useConditionalConfirm,
} from '@opentrons/components'
import { actions as steplistActions } from '../../../../steplist'
import { actions as stepsActions } from '../../../../ui/steps'

import { populateForm } from '../../../../ui/steps/actions/actions'
import {
CLOSE_STEP_FORM_WITH_CHANGES,
CLOSE_UNSAVED_STEP_FORM,
ConfirmDeleteModal,
} from '../../../../components/modals/ConfirmDeleteModal'
import {
getCurrentFormHasUnsavedChanges,
getCurrentFormIsPresaved,
} from '../../../../step-forms/selectors'
import type * as React from 'react'
import type { ThunkDispatch } from 'redux-thunk'
import type { BaseState } from '../../../../types'
import type { StepIdType } from '../../../../form-types'
import { populateForm } from '../../../../ui/steps/actions/actions'
import type { DeleteModalType } from '../../../../components/modals/ConfirmDeleteModal'

interface StepOverflowMenuProps {
stepId: string
Expand All @@ -36,59 +46,91 @@ export function StepOverflowMenu(props: StepOverflowMenuProps): JSX.Element {
const deleteStep = (stepId: StepIdType): void => {
dispatch(steplistActions.deleteStep(stepId))
}
const currentFormIsPresaved = useSelector(getCurrentFormIsPresaved)
const singleEditFormHasUnsavedChanges = useSelector(
getCurrentFormHasUnsavedChanges
)
const duplicateStep = (
stepId: StepIdType
): ReturnType<typeof stepsActions.duplicateStep> =>
dispatch(stepsActions.duplicateStep(stepId))

const handleStepItemSelection = (): void => {
dispatch(populateForm(stepId))
setStepOverflowMenu(false)
}

const { confirm, showConfirmation, cancel } = useConditionalConfirm(
handleStepItemSelection,
currentFormIsPresaved || singleEditFormHasUnsavedChanges
)

const getModalType = (): DeleteModalType => {
if (currentFormIsPresaved) {
return CLOSE_UNSAVED_STEP_FORM
} else {
return CLOSE_STEP_FORM_WITH_CHANGES
}
}

return (
<Flex
ref={menuRootRef}
zIndex={5}
top={top}
left="19.5rem"
position={POSITION_ABSOLUTE}
whiteSpace={NO_WRAP}
borderRadius={BORDERS.borderRadius8}
boxShadow="0px 1px 3px rgba(0, 0, 0, 0.2)"
backgroundColor={COLORS.white}
flexDirection={DIRECTION_COLUMN}
onClick={(e: React.MouseEvent) => {
e.preventDefault()
e.stopPropagation()
}}
>
<MenuButton
onClick={() => {
dispatch(populateForm(stepId))
setStepOverflowMenu(false)
}}
>
{'Edit step'}
</MenuButton>
<MenuButton
onClick={() => {
console.log('wire this up')
}}
>
{t('view_commands')}
</MenuButton>
<MenuButton
onClick={() => {
duplicateStep(stepId)
}}
>
{t('duplicate')}
</MenuButton>
<Divider marginY="0" />
<MenuButton
onClick={() => {
deleteStep(stepId)
<>
{/* TODO: update this modal */}
{showConfirmation && (
<ConfirmDeleteModal
modalType={getModalType()}
onContinueClick={confirm}
onCancelClick={cancel}
/>
)}
<Flex
ref={menuRootRef}
zIndex={5}
top={top}
left="19.5rem"
position={POSITION_ABSOLUTE}
whiteSpace={NO_WRAP}
borderRadius={BORDERS.borderRadius8}
boxShadow="0px 1px 3px rgba(0, 0, 0, 0.2)"
backgroundColor={COLORS.white}
flexDirection={DIRECTION_COLUMN}
onClick={(e: React.MouseEvent) => {
e.preventDefault()
e.stopPropagation()
}}
>
{t('delete')}
</MenuButton>
</Flex>
<MenuButton onClick={confirm}>{t('edit_step')}</MenuButton>
<MenuButton
onClick={() => {
console.log('wire this up')
}}
>
{t('view_commands')}
</MenuButton>
<MenuButton
onClick={() => {
console.log('wire this up')
}}
>
{t('add_details')}
</MenuButton>
<MenuButton
onClick={() => {
duplicateStep(stepId)
}}
>
{t('duplicate')}
</MenuButton>
<Divider marginY="0" />
<MenuButton
onClick={() => {
deleteStep(stepId)
}}
>
{t('delete')}
</MenuButton>
</Flex>
</>
)
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import * as React from 'react'
import { useEffect } from 'react'
import { useDispatch, useSelector } from 'react-redux'
import { useTranslation } from 'react-i18next'
import {
Expand All @@ -25,9 +25,6 @@ import { DraggableSteps } from './DraggableSteps'
import type { StepIdType } from '../../../../form-types'
import type { ThunkDispatch } from '../../../../types'

// interface TimelineToolboxProps {
// setSelectedStep: React.Dispatch<React.SetStateAction<string | null>>
// }
export const TimelineToolbox = (): JSX.Element => {
const { t } = useTranslation('protocol_steps')
const orderedStepIds = useSelector(stepFormSelectors.getOrderedStepIds)
Expand All @@ -50,7 +47,7 @@ export const TimelineToolbox = (): JSX.Element => {
}
}

React.useEffect(() => {
useEffect(() => {
const onKeyDown = (e: KeyboardEvent): void => {
handleKeyDown(e)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,20 @@
import type * as React from 'react'
import { describe, it, vi, beforeEach, expect } from 'vitest'
import '@testing-library/jest-dom/vitest'
import { fireEvent, screen } from '@testing-library/react'
import { renderWithProviders } from '../../../../../__testing-utils__'
import { i18n } from '../../../../../assets/localization'
import { StepOverflowMenu } from '../StepOverflowMenu'
import { deleteStep } from '../../../../../steplist/actions'
import { duplicateStep } from '../../../../../ui/steps/actions/thunks'
import { populateForm } from '../../../../../ui/steps/actions/actions'
import { StepOverflowMenu } from '../StepOverflowMenu'
import {
getCurrentFormHasUnsavedChanges,
getCurrentFormIsPresaved,
} from '../../../../../step-forms/selectors'
import type * as React from 'react'

vi.mock('../../../../../step-forms/selectors')
vi.mock('../../../../../ui/steps/actions/actions')
vi.mock('../../../../../ui/steps/actions/thunks')
vi.mock('../../../../../steplist/actions')
const render = (props: React.ComponentProps<typeof StepOverflowMenu>) => {
Expand All @@ -26,6 +33,8 @@ describe('StepOverflowMenu', () => {
menuRootRef: { current: null },
setStepOverflowMenu: vi.fn(),
}
vi.mocked(getCurrentFormIsPresaved).mockReturnValue(false)
vi.mocked(getCurrentFormHasUnsavedChanges).mockReturnValue(false)
})

it('renders each button and clicking them calls the action', () => {
Expand All @@ -34,8 +43,10 @@ describe('StepOverflowMenu', () => {
expect(vi.mocked(deleteStep)).toHaveBeenCalled()
fireEvent.click(screen.getByText('Duplicate step'))
expect(vi.mocked(duplicateStep)).toHaveBeenCalled()
fireEvent.click(screen.getByText('Edit step'))
expect(vi.mocked(populateForm)).toHaveBeenCalled()
fireEvent.click(screen.getByText('View commands'))
// fireEvent.click(screen.getByText('Rename step'))
// TODO: wire up view commands and rename
fireEvent.click(screen.getByText('Add step details'))
// TODO: wire up view commands and add step details
})
})
7 changes: 0 additions & 7 deletions protocol-designer/src/pages/Designer/ProtocolSteps/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,8 @@ import { StepForm } from './StepForm'
export function ProtocolSteps(): JSX.Element {
const { t } = useTranslation(['starting_deck_state'])
const formData = useSelector(getUnsavedForm)
// const dispatch = useDispatch<any>()
const leftString = t('onDeck')
const rightString = t('offDeck')
// const [selectAStep, setSelectedStep] = useState<string | null>(null)
const [deckView, setDeckView] = useState<
typeof leftString | typeof rightString
>(leftString)
Expand All @@ -35,11 +33,6 @@ export function ProtocolSteps(): JSX.Element {
}
}, [formData, formType, deckView])

// useEffect(() => {
// if (selectAStep != null) {
// dispatch(selectStep(selectAStep))
// }
// })
return (
<>
<StepForm />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,12 +75,6 @@ describe('steps actions', () => {
type: 'SELECT_STEP',
payload: stepId,
},
// {
// type: 'POPULATE_FORM',
// payload: {
// foo: 'getSavedStepFormsResult',
// },
// },
])
})
})
Expand Down
12 changes: 1 addition & 11 deletions protocol-designer/src/ui/steps/actions/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -110,24 +110,13 @@ export const selectStep = (stepId: StepIdType): ThunkAction<any> => (
payload: stepId,
}
dispatch(selectStepAction)
// const state = getState()
// const formData = { ...stepFormSelectors.getSavedStepForms(state)[stepId] }
// dispatch({
// type: 'POPULATE_FORM',
// payload: formData,
// })
resetScrollElements()
}

export const populateForm = (stepId: StepIdType): ThunkAction<any> => (
dispatch: ThunkDispatch<any>,
getState: GetState
) => {
// const selectStepAction: SelectStepAction = {
// type: 'SELECT_STEP',
// payload: stepId,
// }
// dispatch(selectStepAction)
const state = getState()
const formData = { ...stepFormSelectors.getSavedStepForms(state)[stepId] }
dispatch({
Expand All @@ -136,6 +125,7 @@ export const populateForm = (stepId: StepIdType): ThunkAction<any> => (
})
resetScrollElements()
}

// NOTE(sa, 2020-12-11): this is a thunk so that we can populate the batch edit form with things later
export const selectMultipleSteps = (
stepIds: StepIdType[],
Expand Down

0 comments on commit 86b4df9

Please sign in to comment.