diff --git a/frontend/src/exporter/Exporter.stories.tsx b/frontend/src/exporter/Exporter.stories.tsx
index cc64aac00d502..b2be152974a2b 100644
--- a/frontend/src/exporter/Exporter.stories.tsx
+++ b/frontend/src/exporter/Exporter.stories.tsx
@@ -138,6 +138,7 @@ FunnelTopToBottomBreakdownInsight.args = {
}
export const FunnelHistoricalTrendsInsight: Story = Template.bind({})
+FunnelHistoricalTrendsInsight.tags = ['autodocs', 'test-skip']
FunnelHistoricalTrendsInsight.args = {
insight: require('../mocks/fixtures/api/projects/team_id/insights/funnelHistoricalTrends.json'),
}
diff --git a/frontend/src/scenes/pipeline/hogfunctions/HogFunctionInputs.tsx b/frontend/src/scenes/pipeline/hogfunctions/HogFunctionInputs.tsx
index 2b0dac6034ef2..6961e09250b4f 100644
--- a/frontend/src/scenes/pipeline/hogfunctions/HogFunctionInputs.tsx
+++ b/frontend/src/scenes/pipeline/hogfunctions/HogFunctionInputs.tsx
@@ -1,3 +1,6 @@
+import { closestCenter, DndContext } from '@dnd-kit/core'
+import { arrayMove, SortableContext, useSortable, verticalListSortingStrategy } from '@dnd-kit/sortable'
+import { CSS } from '@dnd-kit/utilities'
import { Monaco } from '@monaco-editor/react'
import { IconGear, IconPlus, IconTrash, IconX } from '@posthog/icons'
import {
@@ -7,6 +10,7 @@ import {
LemonInputSelect,
LemonLabel,
LemonSelect,
+ LemonTag,
LemonTextArea,
} from '@posthog/lemon-ui'
import { useActions, useValues } from 'kea'
@@ -362,6 +366,7 @@ function HogFunctionInputSchemaControls({ value, onChange, onDone }: HogFunction
}
export function HogFunctionInputWithSchema({ schema }: HogFunctionInputWithSchemaProps): JSX.Element {
+ const { attributes, listeners, setNodeRef, transform, transition } = useSortable({ id: schema.key })
const { showSource, configuration } = useValues(pipelineHogFunctionConfigurationLogic)
const { setConfigurationValue } = useActions(pipelineHogFunctionConfigurationLogic)
const [editing, setEditing] = useState(showSource)
@@ -394,38 +399,96 @@ export function HogFunctionInputWithSchema({ schema }: HogFunctionInputWithSchem
}
}, [showSource])
- if (!editing) {
- return (
-
- {({ value, onChange }) => {
- return (
- <>
-
- {schema.label || schema.key}
- {showSource ? (
- }
- onClick={() => setEditing(true)}
- />
- ) : null}
-
- onChange({ value: val })}
- />
- >
- )
- }}
-
- )
+ return (
+
+ {!editing ? (
+
+ {({ value, onChange }) => {
+ return (
+ <>
+
+
+ {schema.label || schema.key}
+
+ {showSource ? (
+ <>
+
+ inputs.{schema.key}
+
+
+
}
+ onClick={() => setEditing(true)}
+ />
+ >
+ ) : null}
+
+ onChange({ value: val })}
+ />
+ >
+ )
+ }}
+
+ ) : (
+
+ setEditing(false)}
+ />
+
+ )}
+
+ )
+}
+
+export function HogFunctionInputs(): JSX.Element {
+ const { showSource, configuration } = useValues(pipelineHogFunctionConfigurationLogic)
+ const { setConfigurationValue } = useActions(pipelineHogFunctionConfigurationLogic)
+
+ if (!configuration?.inputs_schema?.length) {
+ return This function does not require any input variables.
}
+ const inputSchemas = configuration.inputs_schema
+ const inputSchemaIds = inputSchemas.map((schema) => schema.key)
+
return (
-
- setEditing(false)} />
-
+ <>
+ {
+ if (over && active.id !== over.id) {
+ const oldIndex = inputSchemaIds.indexOf(active.id as string)
+ const newIndex = inputSchemaIds.indexOf(over.id as string)
+
+ setConfigurationValue('inputs_schema', arrayMove(inputSchemas, oldIndex, newIndex))
+ }
+ }}
+ >
+
+ {configuration.inputs_schema?.map((schema) => {
+ return
+ })}
+
+
+ >
)
}
diff --git a/frontend/src/scenes/pipeline/hogfunctions/PipelineHogFunctionConfiguration.tsx b/frontend/src/scenes/pipeline/hogfunctions/PipelineHogFunctionConfiguration.tsx
index 8faa305bda9f7..71d1dd694a1e6 100644
--- a/frontend/src/scenes/pipeline/hogfunctions/PipelineHogFunctionConfiguration.tsx
+++ b/frontend/src/scenes/pipeline/hogfunctions/PipelineHogFunctionConfiguration.tsx
@@ -25,7 +25,7 @@ import { groupsModel } from '~/models/groupsModel'
import { EntityTypes } from '~/types'
import { HogFunctionIconEditable } from './HogFunctionIcon'
-import { HogFunctionInputWithSchema } from './HogFunctionInputs'
+import { HogFunctionInputs } from './HogFunctionInputs'
import { HogFunctionTest, HogFunctionTestPlaceholder } from './HogFunctionTest'
import { pipelineHogFunctionConfigurationLogic } from './pipelineHogFunctionConfigurationLogic'
@@ -263,15 +263,7 @@ export function PipelineHogFunctionConfiguration({
- {configuration?.inputs_schema?.length ? (
- configuration?.inputs_schema.map((schema, index) => {
- return
- })
- ) : (
-
- This function does not require any input variables.
-
- )}
+
{showSource ? (
<>
diff --git a/frontend/src/scenes/surveys/SurveyEdit.tsx b/frontend/src/scenes/surveys/SurveyEdit.tsx
index c839daa5b7313..9b0372a81a91c 100644
--- a/frontend/src/scenes/surveys/SurveyEdit.tsx
+++ b/frontend/src/scenes/surveys/SurveyEdit.tsx
@@ -8,6 +8,7 @@ import {
LemonButton,
LemonCheckbox,
LemonCollapse,
+ LemonDialog,
LemonDivider,
LemonInput,
LemonSelect,
@@ -51,6 +52,7 @@ export default function SurveyEdit(): JSX.Element {
targetingFlagFilters,
showSurveyRepeatSchedule,
schedule,
+ hasBranchingLogic,
} = useValues(surveyLogic)
const {
setSurveyValue,
@@ -59,6 +61,7 @@ export default function SurveyEdit(): JSX.Element {
setSelectedSection,
setFlagPropertyErrors,
setSchedule,
+ deleteBranchingLogic,
} = useActions(surveyLogic)
const { surveysMultipleQuestionsAvailable, surveysRecurringScheduleAvailable, surveysEventsAvailable } =
useValues(surveysLogic)
@@ -171,10 +174,37 @@ export default function SurveyEdit(): JSX.Element {
{
if (over && active.id !== over.id) {
- onSortEnd({
- oldIndex: sortedItemIds.indexOf(active.id.toString()),
- newIndex: sortedItemIds.indexOf(over.id.toString()),
- })
+ const finishDrag = (): void =>
+ onSortEnd({
+ oldIndex: sortedItemIds.indexOf(active.id.toString()),
+ newIndex: sortedItemIds.indexOf(over.id.toString()),
+ })
+
+ if (hasBranchingLogic) {
+ LemonDialog.open({
+ title: 'Your survey has active branching logic',
+ description: (
+
+ Rearranging questions will remove your branching logic.
+ Are you sure you want to continue?
+
+ ),
+
+ primaryButton: {
+ children: 'Continue',
+ status: 'danger',
+ onClick: () => {
+ deleteBranchingLogic()
+ finishDrag()
+ },
+ },
+ secondaryButton: {
+ children: 'Cancel',
+ },
+ })
+ } else {
+ finishDrag()
+ }
}
}}
>
@@ -226,14 +256,48 @@ export default function SurveyEdit(): JSX.Element {
icon={}
data-attr="delete-survey-confirmation"
onClick={(e) => {
- e.stopPropagation()
- setSelectedPageIndex(
- survey.questions.length - 1
- )
- setSurveyValue('appearance', {
- ...survey.appearance,
- displayThankYouMessage: false,
- })
+ const deleteConfirmationMessage =
+ (): void => {
+ e.stopPropagation()
+ setSelectedPageIndex(
+ survey.questions.length -
+ 1
+ )
+ setSurveyValue('appearance', {
+ ...survey.appearance,
+ displayThankYouMessage:
+ false,
+ })
+ }
+
+ if (hasBranchingLogic) {
+ LemonDialog.open({
+ title: 'Your survey has active branching logic',
+ description: (
+
+ Deleting the
+ confirmation message
+ will remove your
+ branching logic. Are
+ you sure you want to
+ continue?
+
+ ),
+ primaryButton: {
+ children: 'Continue',
+ status: 'danger',
+ onClick: () => {
+ deleteBranchingLogic()
+ deleteConfirmationMessage()
+ },
+ },
+ secondaryButton: {
+ children: 'Cancel',
+ },
+ })
+ } else {
+ deleteConfirmationMessage()
+ }
}}
tooltipPlacement="top-end"
/>
diff --git a/frontend/src/scenes/surveys/SurveyEditQuestionRow.tsx b/frontend/src/scenes/surveys/SurveyEditQuestionRow.tsx
index e1b24b1bea182..c6043bfc6ae3d 100644
--- a/frontend/src/scenes/surveys/SurveyEditQuestionRow.tsx
+++ b/frontend/src/scenes/surveys/SurveyEditQuestionRow.tsx
@@ -4,7 +4,7 @@ import { DraggableSyntheticListeners } from '@dnd-kit/core'
import { useSortable } from '@dnd-kit/sortable'
import { CSS } from '@dnd-kit/utilities'
import { IconPlusSmall, IconTrash } from '@posthog/icons'
-import { LemonButton, LemonCheckbox, LemonInput, LemonSelect } from '@posthog/lemon-ui'
+import { LemonButton, LemonCheckbox, LemonDialog, LemonInput, LemonSelect } from '@posthog/lemon-ui'
import { useActions, useValues } from 'kea'
import { Group } from 'kea-forms'
import { FEATURE_FLAGS } from 'lib/constants'
@@ -38,6 +38,8 @@ export function SurveyEditQuestionHeader({
setSelectedPageIndex,
setSurveyValue,
}: SurveyQuestionHeaderProps): JSX.Element {
+ const { hasBranchingLogic } = useValues(surveyLogic)
+ const { deleteBranchingLogic } = useActions(surveyLogic)
const { setNodeRef, attributes, transform, transition, listeners, isDragging } = useSortable({
id: index.toString(),
})
@@ -71,12 +73,39 @@ export function SurveyEditQuestionHeader({
icon={}
data-attr={`delete-survey-question-${index}`}
onClick={(e) => {
- e.stopPropagation()
- setSelectedPageIndex(index <= 0 ? 0 : index - 1)
- setSurveyValue(
- 'questions',
- survey.questions.filter((_, i) => i !== index)
- )
+ const deleteQuestion = (): void => {
+ e.stopPropagation()
+ setSelectedPageIndex(index <= 0 ? 0 : index - 1)
+ setSurveyValue(
+ 'questions',
+ survey.questions.filter((_, i) => i !== index)
+ )
+ }
+
+ if (hasBranchingLogic) {
+ LemonDialog.open({
+ title: 'Your survey has active branching logic',
+ description: (
+
+ Deleting the question will remove your branching logic. Are you sure you want to
+ continue?
+
+ ),
+ primaryButton: {
+ children: 'Continue',
+ status: 'danger',
+ onClick: () => {
+ deleteBranchingLogic()
+ deleteQuestion()
+ },
+ },
+ secondaryButton: {
+ children: 'Cancel',
+ },
+ })
+ } else {
+ deleteQuestion()
+ }
}}
tooltipPlacement="top-end"
/>
diff --git a/frontend/src/scenes/surveys/surveyLogic.tsx b/frontend/src/scenes/surveys/surveyLogic.tsx
index 62948bdc12a87..2c7f48fd12ea9 100644
--- a/frontend/src/scenes/surveys/surveyLogic.tsx
+++ b/frontend/src/scenes/surveys/surveyLogic.tsx
@@ -170,6 +170,7 @@ export const surveyLogic = kea([
specificQuestionIndex,
}),
resetBranchingForQuestion: (questionIndex) => ({ questionIndex }),
+ deleteBranchingLogic: true,
archiveSurvey: true,
setWritingHTMLDescription: (writingHTML: boolean) => ({ writingHTML }),
setSurveyTemplateValues: (template: any) => ({ template }),
@@ -760,6 +761,17 @@ export const surveyLogic = kea([
questions: newQuestions,
}
},
+ deleteBranchingLogic: (state) => {
+ const newQuestions = [...state.questions]
+ newQuestions.forEach((question) => {
+ delete question.branching
+ })
+
+ return {
+ ...state,
+ questions: newQuestions,
+ }
+ },
},
],
selectedPageIndex: [
@@ -1094,6 +1106,11 @@ export const surveyLogic = kea([
return cycleDetected
},
],
+ hasBranchingLogic: [
+ (s) => [s.survey],
+ (survey) =>
+ survey.questions.some((question) => question.branching && Object.keys(question.branching).length > 0),
+ ],
}),
forms(({ actions, props, values }) => ({
survey: {
diff --git a/package.json b/package.json
index 7b7a450e679da..2327d509d49d0 100644
--- a/package.json
+++ b/package.json
@@ -146,7 +146,7 @@
"pmtiles": "^2.11.0",
"postcss": "^8.4.31",
"postcss-preset-env": "^9.3.0",
- "posthog-js": "1.139.3",
+ "posthog-js": "1.139.4",
"posthog-js-lite": "3.0.0",
"prettier": "^2.8.8",
"prop-types": "^15.7.2",
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 45bdf07dd9d4a..9974d8b091188 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -260,8 +260,8 @@ dependencies:
specifier: ^9.3.0
version: 9.3.0(postcss@8.4.31)
posthog-js:
- specifier: 1.139.3
- version: 1.139.3
+ specifier: 1.139.4
+ version: 1.139.4
posthog-js-lite:
specifier: 3.0.0
version: 3.0.0
@@ -17706,8 +17706,8 @@ packages:
resolution: {integrity: sha512-dyajjnfzZD1tht4N7p7iwf7nBnR1MjVaVu+MKr+7gBgA39bn28wizCIJZztZPtHy4PY0YwtSGgwfBCuG/hnHgA==}
dev: false
- /posthog-js@1.139.3:
- resolution: {integrity: sha512-NmPtOAXogxT/QSmeVCQJeIemBn8rEGfFPIXOynYKgXfntrw0KhzGXXvRXGLVjl5Zx6Nslf5NlmMnzmq1wjLZIA==}
+ /posthog-js@1.139.4:
+ resolution: {integrity: sha512-K0bV3xI7PCgJYN+qPQ26BglOtGzgXHM+BU3pBo1ukbX33O2/CktzFfnKvYdarXuIEBWsRdiiloqb+ok4pI8/Hw==}
dependencies:
fflate: 0.4.8
preact: 10.22.0