- <>
- Minimum session duration
- Minimum session duration (seconds)
+ {
- updateCurrentTeam({ session_recording_minimum_duration_milliseconds: v || null })
+ updateCurrentTeam({ session_recording_minimum_duration_milliseconds: v })
}}
- type={'number'}
- allowClear={true}
+ options={[
+ {
+ label: 'no minimum',
+ value: null,
+ },
+ {
+ label: '1',
+ value: 1000,
+ },
+ {
+ label: '2',
+ value: 2000,
+ },
+ {
+ label: '5',
+ value: 5000,
+ },
+ {
+ label: '10',
+ value: 10000,
+ },
+ {
+ label: '15',
+ value: 15000,
+ },
+ ]}
+ value={currentTeam?.session_recording_minimum_duration_milliseconds}
/>
diff --git a/frontend/src/scenes/teamLogic.tsx b/frontend/src/scenes/teamLogic.tsx
index a30bab40298f0..25775b0825edb 100644
--- a/frontend/src/scenes/teamLogic.tsx
+++ b/frontend/src/scenes/teamLogic.tsx
@@ -69,11 +69,16 @@ export const teamLogic = kea([
return null
}
},
- updateCurrentTeam: async (payload: Partial) => {
+ updateCurrentTeam: async (payload: Partial, breakpoint) => {
if (!values.currentTeam) {
throw new Error('Current team has not been loaded yet, so it cannot be updated!')
}
+
+ await breakpoint(50)
+
const patchedTeam = (await api.update(`api/projects/${values.currentTeam.id}`, payload)) as TeamType
+ breakpoint()
+
actions.loadUser()
/* Notify user the update was successful */
From ca76d1c42e766a8607c617be5e12f4f11ee974c4 Mon Sep 17 00:00:00 2001
From: Paul D'Ambra
Date: Sat, 21 Oct 2023 09:33:55 +0200
Subject: [PATCH 21/39] start adding linked flag
---
frontend/src/lib/components/FlagSelector.tsx | 51 ++++++++++++++++++
.../EarlyAccessFeature.tsx | 53 ++-----------------
.../settings/SessionRecordingSettings.tsx | 23 +++++++-
frontend/src/scenes/surveys/Survey.tsx | 2 +-
frontend/src/scenes/surveys/SurveyEdit.tsx | 2 +-
frontend/src/types.ts | 1 +
posthog/admin.py | 6 +--
posthog/api/team.py | 8 +++
posthog/api/test/test_decide.py | 34 ++++++++++++
posthog/api/test/test_team.py | 48 +++++++++++++++--
.../0356_add_replay_cost_control.py | 7 ++-
posthog/models/team/team.py | 1 +
12 files changed, 174 insertions(+), 62 deletions(-)
create mode 100644 frontend/src/lib/components/FlagSelector.tsx
diff --git a/frontend/src/lib/components/FlagSelector.tsx b/frontend/src/lib/components/FlagSelector.tsx
new file mode 100644
index 0000000000000..74e66ed82049c
--- /dev/null
+++ b/frontend/src/lib/components/FlagSelector.tsx
@@ -0,0 +1,51 @@
+import { useState } from 'react'
+import { useValues } from 'kea'
+import { featureFlagLogic } from 'scenes/feature-flags/featureFlagLogic'
+import { TaxonomicFilterGroupType, TaxonomicFilterLogicProps } from 'lib/components/TaxonomicFilter/types'
+import { Popover } from 'lib/lemon-ui/Popover'
+import { TaxonomicFilter } from 'lib/components/TaxonomicFilter/TaxonomicFilter'
+import { LemonButton } from 'lib/lemon-ui/LemonButton'
+
+interface FlagSelectorProps {
+ value: number | undefined
+ onChange: (id: number, key: string) => void
+ readOnly?: boolean
+}
+
+export function FlagSelector({ value, onChange, readOnly }: FlagSelectorProps): JSX.Element {
+ const [visible, setVisible] = useState(false)
+
+ const { featureFlag } = useValues(featureFlagLogic({ id: value || 'link' }))
+
+ const taxonomicFilterLogicProps: TaxonomicFilterLogicProps = {
+ groupType: TaxonomicFilterGroupType.FeatureFlags,
+ value: value,
+ onChange: (_, __, item) => {
+ 'id' in item && item.id && onChange(item.id, item.key)
+ setVisible(false)
+ },
+ taxonomicGroupTypes: [TaxonomicFilterGroupType.FeatureFlags],
+ optionsFromProp: undefined,
+ popoverEnabled: true,
+ selectFirstItem: true,
+ taxonomicFilterLogicKey: 'flag-selectorz',
+ }
+
+ return (
+ }
+ visible={visible}
+ placement="right-start"
+ fallbackPlacements={['bottom']}
+ onClickOutside={() => setVisible(false)}
+ >
+ {readOnly ? (
+ {featureFlag.key}
+ ) : (
+ setVisible(!visible)}>
+ {featureFlag.key ? featureFlag.key : 'Select flag'}
+
+ )}
+
+ )
+}
diff --git a/frontend/src/scenes/early-access-features/EarlyAccessFeature.tsx b/frontend/src/scenes/early-access-features/EarlyAccessFeature.tsx
index a894b964432cf..7fd04b72e348a 100644
--- a/frontend/src/scenes/early-access-features/EarlyAccessFeature.tsx
+++ b/frontend/src/scenes/early-access-features/EarlyAccessFeature.tsx
@@ -1,5 +1,5 @@
import { LemonButton, LemonDivider, LemonInput, LemonSkeleton, LemonTag, LemonTextArea } from '@posthog/lemon-ui'
-import { useActions, useValues, BindLogic } from 'kea'
+import { BindLogic, useActions, useValues } from 'kea'
import { PageHeader } from 'lib/components/PageHeader'
import { Field, PureField } from 'lib/forms/Field'
import { SceneExport } from 'scenes/sceneTypes'
@@ -16,13 +16,9 @@ import {
import { urls } from 'scenes/urls'
import { IconClose, IconFlag, IconHelpOutline } from 'lib/lemon-ui/icons'
import { router } from 'kea-router'
-import { useState } from 'react'
-import { Popover } from 'lib/lemon-ui/Popover'
-import { TaxonomicFilter } from 'lib/components/TaxonomicFilter/TaxonomicFilter'
-import { TaxonomicFilterLogicProps } from 'lib/components/TaxonomicFilter/types'
import { TaxonomicFilterGroupType } from 'lib/components/TaxonomicFilter/types'
import { featureFlagLogic } from 'scenes/feature-flags/featureFlagLogic'
-import { PersonsLogicProps, personsLogic } from 'scenes/persons/personsLogic'
+import { personsLogic, PersonsLogicProps } from 'scenes/persons/personsLogic'
import clsx from 'clsx'
import { InstructionsModal } from './InstructionsModal'
import { PersonsTable } from 'scenes/persons/PersonsTable'
@@ -31,6 +27,7 @@ import { PersonsSearch } from 'scenes/persons/PersonsSearch'
import { LemonDialog } from 'lib/lemon-ui/LemonDialog'
import { LemonTabs } from 'lib/lemon-ui/LemonTabs'
import { NotFound } from 'lib/components/NotFound'
+import { FlagSelector } from 'lib/components/FlagSelector'
export const scene: SceneExport = {
component: EarlyAccessFeature,
@@ -295,50 +292,6 @@ export function EarlyAccessFeature({ id }: { id?: string } = {}): JSX.Element {
)
}
-interface FlagSelectorProps {
- value: number | undefined
- onChange: (value: any) => void
- readOnly?: boolean
-}
-
-export function FlagSelector({ value, onChange, readOnly }: FlagSelectorProps): JSX.Element {
- const [visible, setVisible] = useState(false)
-
- const { featureFlag } = useValues(featureFlagLogic({ id: value || 'link' }))
-
- const taxonomicFilterLogicProps: TaxonomicFilterLogicProps = {
- groupType: TaxonomicFilterGroupType.FeatureFlags,
- value,
- onChange: (_, __, item) => {
- 'id' in item && item.id && onChange(item.id)
- setVisible(false)
- },
- taxonomicGroupTypes: [TaxonomicFilterGroupType.FeatureFlags],
- optionsFromProp: undefined,
- popoverEnabled: true,
- selectFirstItem: true,
- taxonomicFilterLogicKey: 'flag-selectorz',
- }
-
- return (
- }
- visible={visible}
- placement="right-start"
- fallbackPlacements={['bottom']}
- onClickOutside={() => setVisible(false)}
- >
- {readOnly ? (
- {featureFlag.key}
- ) : (
- setVisible(!visible)}>
- {featureFlag.key ? featureFlag.key : 'Select flag'}
-
- )}
-
- )
-}
-
interface PersonListProps {
earlyAccessFeature: EarlyAccessFeatureType
}
diff --git a/frontend/src/scenes/session-recordings/settings/SessionRecordingSettings.tsx b/frontend/src/scenes/session-recordings/settings/SessionRecordingSettings.tsx
index 631c37809a45f..79f043354a71a 100644
--- a/frontend/src/scenes/session-recordings/settings/SessionRecordingSettings.tsx
+++ b/frontend/src/scenes/session-recordings/settings/SessionRecordingSettings.tsx
@@ -1,6 +1,6 @@
import { useActions, useValues } from 'kea'
import { teamLogic } from 'scenes/teamLogic'
-import { LemonSelect, LemonSwitch, Link } from '@posthog/lemon-ui'
+import { LemonButton, LemonSelect, LemonSwitch, Link } from '@posthog/lemon-ui'
import { urls } from 'scenes/urls'
import { AuthorizedUrlList } from 'lib/components/AuthorizedUrlList/AuthorizedUrlList'
import { AuthorizedUrlListType } from 'lib/components/AuthorizedUrlList/authorizedUrlListLogic'
@@ -9,6 +9,8 @@ import { LemonLabel } from 'lib/lemon-ui/LemonLabel/LemonLabel'
import { FlaggedFeature } from 'lib/components/FlaggedFeature'
import { FEATURE_FLAGS } from 'lib/constants'
import { SampleRate } from '~/types'
+import { IconCancel } from 'lib/lemon-ui/icons'
+import { FlagSelector } from 'lib/components/FlagSelector'
export type SessionRecordingSettingsProps = {
inModal?: boolean
@@ -187,6 +189,25 @@ export function SessionRecordingSettings({ inModal = false }: SessionRecordingSe
Setting a minimum session duration will ensure that only sessions that last longer than that
value are collected. This helps you avoid collecting sessions that are too short to be useful.
+
+ Enable recordings using feature flag
+ {
+ updateCurrentTeam({ session_recording_linked_flag: { id, key } })
+ }}
+ />
+ {currentTeam?.session_recording_linked_flag && (
+ }
+ size="small"
+ status="stealth"
+ onClick={() => updateCurrentTeam({ session_recording_linked_flag: null })}
+ aria-label="close"
+ />
+ )}
+
>
diff --git a/frontend/src/scenes/surveys/Survey.tsx b/frontend/src/scenes/surveys/Survey.tsx
index c3c604a825e4c..a6a74a9ff1877 100644
--- a/frontend/src/scenes/surveys/Survey.tsx
+++ b/frontend/src/scenes/surveys/Survey.tsx
@@ -8,13 +8,13 @@ import { LemonButton, LemonDivider, Link } from '@posthog/lemon-ui'
import { router } from 'kea-router'
import { urls } from 'scenes/urls'
import { Survey, SurveyUrlMatchType } from '~/types'
-import { FlagSelector } from 'scenes/early-access-features/EarlyAccessFeature'
import { SurveyView } from './SurveyView'
import { featureFlagLogic } from 'scenes/feature-flags/featureFlagLogic'
import { NewSurvey, SurveyUrlMatchTypeLabels } from './constants'
import { FeatureFlagReleaseConditions } from 'scenes/feature-flags/FeatureFlagReleaseConditions'
import SurveyEdit from './SurveyEdit'
import { NotFound } from 'lib/components/NotFound'
+import { FlagSelector } from 'lib/components/FlagSelector'
export const scene: SceneExport = {
component: SurveyComponent,
diff --git a/frontend/src/scenes/surveys/SurveyEdit.tsx b/frontend/src/scenes/surveys/SurveyEdit.tsx
index 9b8b0b41f8a08..2fccef0e4da7b 100644
--- a/frontend/src/scenes/surveys/SurveyEdit.tsx
+++ b/frontend/src/scenes/surveys/SurveyEdit.tsx
@@ -22,7 +22,6 @@ import {
RatingSurveyQuestion,
SurveyUrlMatchType,
} from '~/types'
-import { FlagSelector } from 'scenes/early-access-features/EarlyAccessFeature'
import { IconCancel, IconDelete, IconPlus, IconPlusMini } from 'lib/lemon-ui/icons'
import {
BaseAppearance,
@@ -45,6 +44,7 @@ import { CodeEditor } from 'lib/components/CodeEditors'
import { FEATURE_FLAGS } from 'lib/constants'
import { featureFlagLogic as enabledFeaturesLogic } from 'lib/logic/featureFlagLogic'
import { SurveyFormAppearance } from './SurveyFormAppearance'
+import { FlagSelector } from 'lib/components/FlagSelector'
function PresentationTypeCard({
title,
diff --git a/frontend/src/types.ts b/frontend/src/types.ts
index 066c15c7b9c08..d7005ba69d72b 100644
--- a/frontend/src/types.ts
+++ b/frontend/src/types.ts
@@ -341,6 +341,7 @@ export interface TeamType extends TeamBasicType {
capture_performance_opt_in: boolean
session_recording_sample_rate: SampleRate
session_recording_minimum_duration_milliseconds: number | null
+ session_recording_linked_flag: Pick