Skip to content

Commit adc0558

Browse files
committed
feat(surveys): experiment with create survey button on experiments
1 parent 4ca3d2c commit adc0558

File tree

3 files changed

+87
-17
lines changed

3 files changed

+87
-17
lines changed

frontend/src/lib/constants.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -351,6 +351,7 @@ export const FEATURE_FLAGS = {
351351
SURVEYS_FF_CROSS_SELL: 'surveys-ff-cross-sell', // owner: @adboio #team-surveys
352352
SURVEYS_INSIGHT_BUTTON_EXPERIMENT: 'ask-users-why-ai-vs-quickcreate', // owner: @adboio #team-surveys multivariate
353353
SURVEYS_EXPERIMENTS_CROSS_SELL: 'surveys-experiments-cross-sell', // owner: @adboio #team-surveys
354+
SURVEYS_EXPERIMENTS_BUTTON_EXPERIMENT: 'create-survey-from-experiment---ai-vs-modal', // owner: @adboio #team-surveys multivariate
354355
} as const
355356
export type FeatureFlagLookupKey = keyof typeof FEATURE_FLAGS
356357
export type FeatureFlagKey = (typeof FEATURE_FLAGS)[keyof typeof FEATURE_FLAGS]

frontend/src/scenes/experiments/ExperimentView/components.tsx

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -29,12 +29,12 @@ import { IconAreaChart } from 'lib/lemon-ui/icons'
2929
import { ButtonPrimitive } from 'lib/ui/Button/ButtonPrimitives'
3030
import { userHasAccess } from 'lib/utils/accessControlUtils'
3131
import { addProductIntent } from 'lib/utils/product-intents'
32-
import { useMaxTool } from 'scenes/max/useMaxTool'
3332
import { sceneLogic } from 'scenes/sceneLogic'
3433
import { SURVEY_CREATED_SOURCE } from 'scenes/surveys/constants'
34+
import { QuickSurveyModal } from 'scenes/surveys/quick-create/QuickSurveyModal'
35+
import { QuickSurveyType } from 'scenes/surveys/quick-create/types'
3536
import { captureMaxAISurveyCreationException } from 'scenes/surveys/utils'
3637
import { urls } from 'scenes/urls'
37-
import { userLogic } from 'scenes/userLogic'
3838

3939
import { iconForType } from '~/layout/panel-layout/ProjectTree/defaultTree'
4040
import { ScenePanel, ScenePanelActionsSection } from '~/layout/scenes/SceneLayout'
@@ -65,6 +65,7 @@ import {
6565
} from '~/types'
6666

6767
import { DuplicateExperimentModal } from '../DuplicateExperimentModal'
68+
import { useExperimentSurvey } from '../Experiments'
6869
import { CONCLUSION_DISPLAY_CONFIG, EXPERIMENT_VARIANT_MULTIPLE } from '../constants'
6970
import { experimentLogic } from '../experimentLogic'
7071
import { getExperimentStatusColor } from '../experimentsLogic'
@@ -421,11 +422,14 @@ export function PageHeaderCustom(): JSX.Element {
421422
setHogfettiTrigger,
422423
} = useActions(experimentLogic)
423424
const { openShipVariantModal, openStopExperimentModal } = useActions(modalsLogic)
424-
const { user } = useValues(userLogic)
425425
const [duplicateModalOpen, setDuplicateModalOpen] = useState(false)
426+
const [surveyModalOpen, setSurveyModalOpen] = useState(false)
426427
const { newTab } = useActions(sceneLogic)
427-
// Initialize MaxTool hook for experiment survey creation
428-
const { openMax } = useMaxTool(createMaxToolExperimentSurveyConfig(experiment, user))
428+
const {
429+
handleClick: handleSurveyClick,
430+
isDisabled: isSurveyDisabled,
431+
hasFeatureFlag: surveyHasFeatureFlag,
432+
} = useExperimentSurvey(experiment, () => setSurveyModalOpen(true))
429433
const { trigger, HogfettiComponent } = useHogfetti()
430434

431435
useOnMountEffect(() => {
@@ -578,12 +582,12 @@ export function PageHeaderCustom(): JSX.Element {
578582
<IconPlusSmall /> Create dashboard
579583
</ButtonPrimitive>
580584

581-
{experiment.feature_flag && (
585+
{surveyHasFeatureFlag && (
582586
<ButtonPrimitive
583587
menuItem
584-
onClick={openMax || undefined}
588+
onClick={handleSurveyClick}
585589
disabledReasons={{
586-
'PostHog AI not available': !openMax,
590+
'PostHog AI not available': isSurveyDisabled,
587591
}}
588592
>
589593
<IconPlusSmall /> Create survey
@@ -607,6 +611,11 @@ export function PageHeaderCustom(): JSX.Element {
607611
</ScenePanelActionsSection>
608612
</ScenePanel>
609613
)}
614+
<QuickSurveyModal
615+
context={{ type: QuickSurveyType.EXPERIMENT, experiment }}
616+
isOpen={surveyModalOpen}
617+
onCancel={() => setSurveyModalOpen(false)}
618+
/>
610619
</>
611620
)
612621
}

frontend/src/scenes/experiments/Experiments.tsx

Lines changed: 69 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import { ActivityLog } from 'lib/components/ActivityLog/ActivityLog'
1010
import { MemberSelect } from 'lib/components/MemberSelect'
1111
import { ProductIntroduction } from 'lib/components/ProductIntroduction/ProductIntroduction'
1212
import { ExperimentsHog } from 'lib/components/hedgehogs'
13+
import { FEATURE_FLAGS } from 'lib/constants'
1314
import { dayjs } from 'lib/dayjs'
1415
import { LemonButton } from 'lib/lemon-ui/LemonButton'
1516
import { More } from 'lib/lemon-ui/LemonButton/More'
@@ -18,11 +19,14 @@ import { LemonTable, LemonTableColumn, LemonTableColumns } from 'lib/lemon-ui/Le
1819
import { LemonTableLink } from 'lib/lemon-ui/LemonTable/LemonTableLink'
1920
import { atColumn, createdAtColumn, createdByColumn } from 'lib/lemon-ui/LemonTable/columnUtils'
2021
import { LemonTabs } from 'lib/lemon-ui/LemonTabs'
22+
import { featureFlagLogic } from 'lib/logic/featureFlagLogic'
2123
import { deleteWithUndo } from 'lib/utils/deleteWithUndo'
2224
import stringWithWBR from 'lib/utils/stringWithWBR'
2325
import MaxTool from 'scenes/max/MaxTool'
2426
import { useMaxTool } from 'scenes/max/useMaxTool'
2527
import { SceneExport } from 'scenes/sceneTypes'
28+
import { QuickSurveyModal } from 'scenes/surveys/quick-create/QuickSurveyModal'
29+
import { QuickSurveyType } from 'scenes/surveys/quick-create/types'
2630
import { urls } from 'scenes/urls'
2731
import { userLogic } from 'scenes/userLogic'
2832

@@ -55,23 +59,56 @@ export const scene: SceneExport = {
5559
export const EXPERIMENTS_PRODUCT_DESCRIPTION =
5660
'Experiments help you test changes to your product to see which changes will lead to optimal results. Automatic statistical calculations let you see if the results are valid or if they are likely just a chance occurrence.'
5761

58-
// Component for the survey button using MaxTool
59-
const ExperimentSurveyButton = ({ experiment }: { experiment: Experiment }): JSX.Element => {
62+
export function useExperimentSurvey(
63+
experiment: Experiment,
64+
onOpenModal?: () => void
65+
): {
66+
handleClick: () => void
67+
isDisabled: boolean
68+
hasFeatureFlag: boolean
69+
} {
6070
const { user } = useValues(userLogic)
6171
const { openMax } = useMaxTool(createMaxToolExperimentSurveyConfig(experiment, user))
72+
const { featureFlags } = useValues(featureFlagLogic)
73+
74+
const shouldUseQuickCreate = featureFlags[FEATURE_FLAGS.SURVEYS_EXPERIMENTS_BUTTON_EXPERIMENT] === 'test'
75+
76+
const handleClick = (): void => {
77+
if (shouldUseQuickCreate) {
78+
onOpenModal?.()
79+
} else {
80+
openMax?.()
81+
}
82+
}
83+
84+
return {
85+
handleClick,
86+
isDisabled: !shouldUseQuickCreate && !openMax,
87+
hasFeatureFlag: !!experiment.feature_flag,
88+
}
89+
}
90+
91+
const ExperimentSurveyButton = ({
92+
experiment,
93+
onOpenModal,
94+
}: {
95+
experiment: Experiment
96+
onOpenModal: () => void
97+
}): JSX.Element | null => {
98+
const { handleClick, isDisabled, hasFeatureFlag } = useExperimentSurvey(experiment, onOpenModal)
6299

63100
// Don't show the button if there's no feature flag associated with the experiment
64-
if (!experiment.feature_flag) {
65-
return <></>
101+
if (!hasFeatureFlag) {
102+
return null
66103
}
67104

68105
return (
69106
<LemonButton
70-
onClick={openMax || undefined}
107+
onClick={handleClick}
71108
size="small"
72109
fullWidth
73110
data-attr="create-survey"
74-
disabled={!openMax}
111+
disabledReason={isDisabled ? 'PostHog AI not available' : undefined}
75112
>
76113
Create survey
77114
</LemonButton>
@@ -158,8 +195,10 @@ const ExperimentsTableFilters = ({
158195

159196
const ExperimentsTable = ({
160197
openDuplicateModal,
198+
openSurveyModal,
161199
}: {
162200
openDuplicateModal: (experiment: Experiment) => void
201+
openSurveyModal: (experiment: Experiment) => void
163202
}): JSX.Element => {
164203
const { currentProjectId, experiments, experimentsLoading, tab, shouldShowEmptyState, filters, count, pagination } =
165204
useValues(experimentsLogic)
@@ -255,7 +294,10 @@ const ExperimentsTable = ({
255294
<LemonButton onClick={() => openDuplicateModal(experiment)} size="small" fullWidth>
256295
Duplicate
257296
</LemonButton>
258-
<ExperimentSurveyButton experiment={experiment} />
297+
<ExperimentSurveyButton
298+
experiment={experiment}
299+
onOpenModal={() => openSurveyModal(experiment)}
300+
/>
259301
{!experiment.archived &&
260302
experiment?.end_date &&
261303
dayjs().isSameOrAfter(dayjs(experiment.end_date), 'day') && (
@@ -425,6 +467,7 @@ export function Experiments(): JSX.Element {
425467
const { setExperimentsTab, loadExperiments } = useActions(experimentsLogic)
426468

427469
const [duplicateModalExperiment, setDuplicateModalExperiment] = useState<Experiment | null>(null)
470+
const [surveyModalExperiment, setSurveyModalExperiment] = useState<Experiment | null>(null)
428471

429472
// Register feature flag creation tool so that it's always available on experiments page
430473
useMaxTool({
@@ -497,12 +540,22 @@ export function Experiments(): JSX.Element {
497540
{
498541
key: ExperimentsTabs.All,
499542
label: 'All experiments',
500-
content: <ExperimentsTable openDuplicateModal={setDuplicateModalExperiment} />,
543+
content: (
544+
<ExperimentsTable
545+
openDuplicateModal={setDuplicateModalExperiment}
546+
openSurveyModal={setSurveyModalExperiment}
547+
/>
548+
),
501549
},
502550
{
503551
key: ExperimentsTabs.Archived,
504552
label: 'Archived experiments',
505-
content: <ExperimentsTable openDuplicateModal={setDuplicateModalExperiment} />,
553+
content: (
554+
<ExperimentsTable
555+
openDuplicateModal={setDuplicateModalExperiment}
556+
openSurveyModal={setSurveyModalExperiment}
557+
/>
558+
),
506559
},
507560
{
508561
key: ExperimentsTabs.SharedMetrics,
@@ -529,6 +582,13 @@ export function Experiments(): JSX.Element {
529582
experiment={duplicateModalExperiment}
530583
/>
531584
)}
585+
{surveyModalExperiment && (
586+
<QuickSurveyModal
587+
context={{ type: QuickSurveyType.EXPERIMENT, experiment: surveyModalExperiment }}
588+
isOpen={true}
589+
onCancel={() => setSurveyModalExperiment(null)}
590+
/>
591+
)}
532592
</SceneContent>
533593
)
534594
}

0 commit comments

Comments
 (0)