Skip to content

Commit

Permalink
chore: improve generation of experiment flag key (#27794)
Browse files Browse the repository at this point in the history
  • Loading branch information
joshsny authored Jan 23, 2025
1 parent f784a46 commit 7d585a2
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 14 deletions.
20 changes: 10 additions & 10 deletions frontend/src/scenes/experiments/ExperimentForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,8 @@ const ExperimentFormFields = (): JSX.Element => {
const { experiment, groupTypes, aggregationLabel } = useValues(experimentLogic)
const { addVariant, removeExperimentGroup, setExperiment, createExperiment, setExperimentType } =
useActions(experimentLogic)
const { webExperimentsAvailable } = useValues(experimentsLogic)
const { webExperimentsAvailable, unavailableFeatureFlagKeys } = useValues(experimentsLogic)
const { groupsAccessStatus } = useValues(groupsAccessLogic)
const { takenKeys } = useValues(experimentsLogic)

return (
<div>
Expand All @@ -40,14 +39,14 @@ const ExperimentFormFields = (): JSX.Element => {
<LemonButton
type="secondary"
size="xsmall"
tooltip={
experiment.name
? 'Generate a key from the experiment name'
: 'Fill out the experiment name first.'
}
disabledReason={experiment.name ? undefined : 'Fill out the experiment name first.'}
tooltip={experiment.name ? 'Generate a key from the experiment name' : undefined}
onClick={() => {
setExperiment({
feature_flag_key: generateFeatureFlagKey(experiment.name, takenKeys),
feature_flag_key: generateFeatureFlagKey(
experiment.name,
unavailableFeatureFlagKeys
),
})
}}
>
Expand Down Expand Up @@ -294,7 +293,7 @@ export function ExperimentForm(): JSX.Element {
)
}

const generateFeatureFlagKey = (name: string, takenKeys: string[]): string => {
const generateFeatureFlagKey = (name: string, unavailableFeatureFlagKeys: Set<string>): string => {
const baseKey = name
.toLowerCase()
.replace(/[^A-Za-z0-9-_]+/g, '-')
Expand All @@ -303,7 +302,8 @@ const generateFeatureFlagKey = (name: string, takenKeys: string[]): string => {

let key = baseKey
let counter = 1
while (takenKeys.includes(key)) {

while (unavailableFeatureFlagKeys.has(key)) {
key = `${baseKey}-${counter}`
counter++
}
Expand Down
16 changes: 12 additions & 4 deletions frontend/src/scenes/experiments/experimentsLogic.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import api from 'lib/api'
import { FEATURE_FLAGS } from 'lib/constants'
import { lemonToast } from 'lib/lemon-ui/LemonToast/LemonToast'
import { featureFlagLogic, FeatureFlagsSet } from 'lib/logic/featureFlagLogic'
import { featureFlagsLogic, type FeatureFlagsResult } from 'scenes/feature-flags/featureFlagsLogic'
import { projectLogic } from 'scenes/projectLogic'
import { userLogic } from 'scenes/userLogic'

Expand Down Expand Up @@ -44,6 +45,8 @@ export const experimentsLogic = kea<experimentsLogicType>([
['user', 'hasAvailableFeature'],
featureFlagLogic,
['featureFlags'],
featureFlagsLogic,
['featureFlags'],
router,
['location'],
],
Expand Down Expand Up @@ -161,10 +164,15 @@ export const experimentsLogic = kea<experimentsLogicType>([
() => [featureFlagLogic.selectors.featureFlags],
(featureFlags: FeatureFlagsSet) => featureFlags[FEATURE_FLAGS.WEB_EXPERIMENTS],
],
// This only checks the first page, which is very large so it's not a big deal
takenKeys: [
(s) => [s.experiments],
(experiments: Experiment[]) => experiments.map((experiment) => experiment.feature_flag_key),
// TRICKY: we do not load all feature flags here, just the latest ones.
unavailableFeatureFlagKeys: [
(s) => [featureFlagsLogic.selectors.featureFlags, s.experiments],
(featureFlags: FeatureFlagsResult, experiments: Experiment[]) => {
return new Set([
...featureFlags.results.map((flag) => flag.key),
...experiments.map((experiment) => experiment.feature_flag_key),
])
},
],
})),
events(({ actions }) => ({
Expand Down

0 comments on commit 7d585a2

Please sign in to comment.