Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

32 changes: 32 additions & 0 deletions apps/journeys-admin/__generated__/StepBlockNextBlockUpdate.ts

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
import { MockedProvider } from '@apollo/client/testing'
import { EditorProvider, TreeBlock } from '@core/journeys/ui'
import { fireEvent, render, waitFor } from '@testing-library/react'
import { JourneyProvider } from '../../../../../../../../libs/context'
import {
GetJourney_journey_blocks_StepBlock as StepBlock,
GetJourney_journey as Journey
} from '../../../../../../../../../__generated__/GetJourney'
import {
ThemeName,
ThemeMode
} from '../../../../../../../../../__generated__/globalTypes'
import { Cards, STEP_BLOCK_NEXT_BLOCK_UPDATE } from './Cards'

describe('Cards', () => {
it('updates the next step on click', async () => {
const selectedBlock: TreeBlock<StepBlock> = {
id: 'step1.id',
__typename: 'StepBlock',
parentBlockId: null,
nextBlockId: 'step2.id',
parentOrder: 0,
locked: false,
children: []
}

const nextBlock: TreeBlock<StepBlock> = {
id: 'step2.id',
__typename: 'StepBlock',
parentBlockId: null,
nextBlockId: 'step0.id',
parentOrder: 0,
locked: false,
children: []
}

const steps = [selectedBlock, nextBlock]

const result = jest.fn(() => ({
data: {
stepBlockUpdate: {
id: 'step1.id',
nextBlockId: 'step2.id'
}
}
}))

const { getByTestId } = render(
<MockedProvider
mocks={[
{
request: {
query: STEP_BLOCK_NEXT_BLOCK_UPDATE,
variables: {
id: selectedBlock.id,
journeyId: 'journeyId',
input: {
nextBlockId: selectedBlock.nextBlockId
}
}
},
result
}
]}
>
<JourneyProvider
value={
{
id: 'journeyId',
themeMode: ThemeMode.light,
themeName: ThemeName.base
} as unknown as Journey
}
>
<EditorProvider initialState={{ steps, selectedBlock }}>
<Cards />
</EditorProvider>
</JourneyProvider>
</MockedProvider>
)

fireEvent.click(getByTestId('preview-step2.id'))
await waitFor(() => expect(result).toHaveBeenCalled())
})
})
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import { ReactElement } from 'react'
import { useTheme } from '@mui/material'
import { gql, useMutation } from '@apollo/client'
import Box from '@mui/material/Box'
import Typography from '@mui/material/Typography'
import { useEditor, TreeBlock } from '@core/journeys/ui'
import { useJourney } from '../../../../../../../../libs/context'
import { StepFields } from '../../../../../../../../../__generated__/StepFields'
import { StepBlockNextBlockUpdate } from '../../../../../../../../../__generated__/StepBlockNextBlockUpdate'
import { CardPreview } from '../../../../../../../CardPreview'

export const STEP_BLOCK_NEXT_BLOCK_UPDATE = gql`
mutation StepBlockNextBlockUpdate(
$id: ID!
$journeyId: ID!
$input: StepBlockUpdateInput!
) {
stepBlockUpdate(id: $id, journeyId: $journeyId, input: $input) {
id
nextBlockId
}
}
`

export function Cards(): ReactElement {
const [stepBlockNextBlockUpdate] = useMutation<StepBlockNextBlockUpdate>(
STEP_BLOCK_NEXT_BLOCK_UPDATE
)
const {
state: { steps, selectedBlock }
} = useEditor()
const journey = useJourney()
const theme = useTheme()
const { id, nextBlockId } = selectedBlock as TreeBlock<StepFields>

const nextStep: TreeBlock<StepFields> | undefined = steps.find(
({ id }) => nextBlockId === id
)

async function handleSelectStep(step: TreeBlock<StepFields>): Promise<void> {
await stepBlockNextBlockUpdate({
variables: {
id,
journeyId: journey.id,
input: {
nextBlockId: step.id
}
},
optimisticResponse: {
stepBlockUpdate: {
id,
__typename: 'StepBlock',
nextBlockId: step.id
}
}
})
}

return (
<>
<Box sx={{ pl: 6, pr: 4, pt: 4 }}>
<Typography
variant="subtitle2"
sx={{ [theme.breakpoints.down('sm')]: { display: 'none' } }}
>
Cards
</Typography>
</Box>
<CardPreview
selected={nextStep}
steps={steps}
onSelect={handleSelectStep}
/>
</>
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { Cards, STEP_BLOCK_NEXT_BLOCK_UPDATE } from './Cards'
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import { MockedProvider } from '@apollo/client/testing'
import { EditorProvider, TreeBlock } from '@core/journeys/ui'
import { fireEvent, render, waitFor } from '@testing-library/react'
import { JourneyProvider } from '../../../../../../../../libs/context'
import {
GetJourney_journey_blocks_StepBlock as StepBlock,
GetJourney_journey as Journey
} from '../../../../../../../../../__generated__/GetJourney'
import { Conditions, STEP_BLOCK_LOCK_UPDATE } from './Conditions'

describe('Conditions', () => {
it('changes the locked step state on click', async () => {
const selectedBlock: TreeBlock<StepBlock> = {
id: 'step1.id',
__typename: 'StepBlock',
parentBlockId: null,
nextBlockId: 'step2.id',
parentOrder: 0,
locked: false,
children: []
}

const result = jest.fn(() => ({
data: {
stepBlockUpdate: {
id: 'step1.id',
locked: false
}
}
}))

const { getByRole } = render(
<MockedProvider
mocks={[
{
request: {
query: STEP_BLOCK_LOCK_UPDATE,
variables: {
id: selectedBlock.id,
journeyId: 'journeyId',
input: {
locked: true
}
}
},
result
}
]}
>
<JourneyProvider value={{ id: 'journeyId' } as unknown as Journey}>
<EditorProvider initialState={{ selectedBlock }}>
<Conditions />
</EditorProvider>
</JourneyProvider>
</MockedProvider>
)

expect(getByRole('checkbox')).not.toBeChecked()
fireEvent.click(getByRole('checkbox'))
await waitFor(() => expect(result).toHaveBeenCalled())
})
})
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import { ReactElement } from 'react'
import { useTheme } from '@mui/material'
import Box from '@mui/material/Box'
import Typography from '@mui/material/Typography'
import { gql, useMutation } from '@apollo/client'
import InfoOutlinedIcon from '@mui/icons-material/InfoOutlined'
import { TreeBlock, useEditor } from '@core/journeys/ui'
import { useJourney } from '../../../../../../../../libs/context'
import { StepFields } from '../../../../../../../../../__generated__/StepFields'

import { StepBlockLockUpdate } from '../../../../../../../../../__generated__/StepBlockLockUpdate'
import { ToggleOption } from '../../../../ToggleOption'

export const STEP_BLOCK_LOCK_UPDATE = gql`
mutation StepBlockLockUpdate(
$id: ID!
$journeyId: ID!
$input: StepBlockUpdateInput!
) {
stepBlockUpdate(id: $id, journeyId: $journeyId, input: $input) {
id
locked
}
}
`

export function Conditions(): ReactElement {
const [stepBlockLockUpdate] = useMutation<StepBlockLockUpdate>(
STEP_BLOCK_LOCK_UPDATE
)
const {
state: { selectedBlock }
} = useEditor()
const journey = useJourney()
const theme = useTheme()
const block = selectedBlock as TreeBlock<StepFields>

async function handleChange(): Promise<void> {
await stepBlockLockUpdate({
variables: {
id: block.id,
journeyId: journey.id,
input: {
locked: !block.locked
}
},
optimisticResponse: {
stepBlockUpdate: {
id: block.id,
__typename: 'StepBlock',
locked: !block.locked
}
}
})
}

return (
<Box sx={{ p: 4, pl: 6 }}>
<Typography
variant="subtitle2"
gutterBottom
sx={{ [theme.breakpoints.down('sm')]: { display: 'none' }, mb: 4 }}
>
Conditions
</Typography>
<ToggleOption
heading={'Lock the next step'}
description={"Don't allow to skip the current card"}
checked={block.locked}
handleChange={handleChange}
>
<Box display={'flex'} alignItems={'center'} color={'text.secondary'}>
<InfoOutlinedIcon sx={{ mr: 4 }} />
<Typography variant="caption">
User can&apos;t skip interaction on the current card, like watching
video or interacting with questions.
</Typography>
</Box>
</ToggleOption>
</Box>
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { Conditions } from './Conditions'
Loading