Skip to content
Draft
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
4 changes: 3 additions & 1 deletion products/workflows/frontend/Workflows/WorkflowsTable.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useActions, useValues } from 'kea'
import { useActions, useMountedLogic, useValues } from 'kea'
import { useMemo } from 'react'

import {
Expand Down Expand Up @@ -47,6 +47,7 @@
workflowsLogic,
} from './workflowsLogic'
import { WorkflowStepMatches } from './WorkflowStepMatches'
import { workflowsWaitingRefreshLogic } from './workflowsWaitingRefreshLogic'
import { WorkflowTagsCell } from './WorkflowTagsCell'
import { hasMessagingAction } from './workflowTypeFilters'

Expand Down Expand Up @@ -120,11 +121,12 @@
)
}

export function WorkflowsTable(): JSX.Element {

Check warning on line 124 in products/workflows/frontend/Workflows/WorkflowsTable.tsx

View workflow job for this annotation

GitHub Actions / Frontend formatting

lint:complexity

`WorkflowsTable` has cyclomatic complexity 13 (warn >10)
const { featureFlags } = useValues(featureFlagLogic)
const overviewTabEnabled = !!featureFlags[FEATURE_FLAGS.WORKFLOWS_OVERVIEW_TAB]
const { suggestionsAvailable } = useValues(workflowSuggestionsAvailabilityLogic)
const logic = workflowsLogic()
useMountedLogic(workflowsWaitingRefreshLogic)
const {
workflowsLoading,
workflows,
Expand Down Expand Up @@ -212,7 +214,7 @@
title: 'Name',
key: 'name',
sorter: (a, b) => (a.name || '').localeCompare(b.name || ''),
render: (_, item) => {

Check warning on line 217 in products/workflows/frontend/Workflows/WorkflowsTable.tsx

View workflow job for this annotation

GitHub Actions / Frontend formatting

lint:complexity

`render` has cyclomatic complexity 12 (warn >10)
const stepMatches = findMatchingWorkflowSteps(item, filters.search)
return (
<div className="min-w-48">
Expand Down
15 changes: 15 additions & 0 deletions products/workflows/frontend/Workflows/waitingStatusCheck.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
const WAITING_STATUS_CHECK_INTERVAL_MS = 10_000

interface Disposables {
add: (setup: () => () => void) => void
}

export function checkWaitingStatusWhileVisible(disposables: Disposables, checkStatus: () => void): void {
// Setup runs again each time a hidden tab shows. The person often verifies the domain in another
// tab, so check at once on return instead of waiting for the next tick.
disposables.add(() => {
checkStatus()
const timer = window.setInterval(checkStatus, WAITING_STATUS_CHECK_INTERVAL_MS)
return () => clearInterval(timer)
})
}
Original file line number Diff line number Diff line change
Expand Up @@ -381,27 +381,45 @@ describe('workflowLogic auto-save', () => {
expect(logic.values.hasStagedDraft).toBe(false)
})

it('reports enabling a workflow once, with the product surface it was opened from', async () => {
const captureSpy = jest.spyOn(posthog, 'capture')
saveEntrySource(WORKFLOW_ID, 'survey')
useMocks(activeMocks({ ...activeWorkflow, status: 'draft' }))
initKeaTests()
logic = workflowLogic({ id: WORKFLOW_ID })
logic.mount()
await expectLogic(logic).toDispatchActions(['loadWorkflowSuccess'])

await expectLogic(logic, () => {
logic.actions.saveWorkflowPartial({ status: 'active' })
}).toDispatchActions(['saveWorkflowSuccess'])
await expectLogic(logic, () => {
logic.actions.setWorkflowValue('name', 'Renamed while live')
logic.actions.saveWorkflowPartial({ name: 'Renamed while live' })
}).toDispatchActions(['saveWorkflowSuccess'])

const enabledCalls = captureSpy.mock.calls.filter(([event]) => event === 'workflow enabled')
expect(enabledCalls).toEqual([['workflow enabled', { workflow_id: WORKFLOW_ID, entry_source: 'survey' }]])
captureSpy.mockRestore()
})
it.each([
['goes live', 'active', [['workflow enabled', { workflow_id: WORKFLOW_ID, entry_source: 'survey' }]]],
['waits for its email domain', 'waiting_for_domain', []],
] as [string, HogFlow['status'], unknown[]][])(
'reports an enable that %s at most once, with the product surface it was opened from',
async (_name, enabledStatus, expectedCalls) => {
const captureSpy = jest.spyOn(posthog, 'capture')
saveEntrySource(WORKFLOW_ID, 'survey')
const draftWorkflow: HogFlow = { ...activeWorkflow, status: 'draft' }
// The enable lands with `enabledStatus`; by the next save the domain has verified.
const responseStatuses: HogFlow['status'][] = [enabledStatus, 'active']
useMocks({
...activeMocks(draftWorkflow),
patch: {
'/api/environments/:team_id/hog_flows/:id/': async ({ request }) => {
const body = (await request.json()) as Record<string, any>
return [200, { ...draftWorkflow, ...body, status: responseStatuses.shift() }]
},
},
})
initKeaTests()
logic = workflowLogic({ id: WORKFLOW_ID })
logic.mount()
await expectLogic(logic).toDispatchActions(['loadWorkflowSuccess'])

await expectLogic(logic, () => {
logic.actions.saveWorkflowPartial({ status: 'active' })
}).toDispatchActions(['saveWorkflowSuccess'])
await expectLogic(logic, () => {
logic.actions.setWorkflowValue('name', 'Renamed while live')
logic.actions.markAutoSave(true)
logic.actions.saveWorkflow(logic.values.workflow)
}).toDispatchActions(['saveWorkflowSuccess'])

const enabledCalls = captureSpy.mock.calls.filter(([event]) => event === 'workflow enabled')
expect(enabledCalls).toEqual(expectedCalls)
captureSpy.mockRestore()
}
)

it('a status transition sends lifecycle and metadata only, never stage_draft', async () => {
useMocks(
Expand Down
Loading
Loading