fix(settings): Hide "Product description" setting for no-AI users (#26290)
Co-authored-by: github-actions <41898282+github-actions[bot]@users.noreply.github.com>
Before Width: | Height: | Size: 104 KiB After Width: | Height: | Size: 112 KiB |
Before Width: | Height: | Size: 106 KiB After Width: | Height: | Size: 114 KiB |
Before Width: | Height: | Size: 724 KiB After Width: | Height: | Size: 709 KiB |
Before Width: | Height: | Size: 722 KiB After Width: | Height: | Size: 706 KiB |
Before Width: | Height: | Size: 758 KiB After Width: | Height: | Size: 743 KiB |
Before Width: | Height: | Size: 756 KiB After Width: | Height: | Size: 740 KiB |
Before Width: | Height: | Size: 724 KiB After Width: | Height: | Size: 709 KiB |
Before Width: | Height: | Size: 722 KiB After Width: | Height: | Size: 706 KiB |
Before Width: | Height: | Size: 724 KiB After Width: | Height: | Size: 709 KiB |
Before Width: | Height: | Size: 722 KiB After Width: | Height: | Size: 706 KiB |
Before Width: | Height: | Size: 724 KiB After Width: | Height: | Size: 709 KiB |
Before Width: | Height: | Size: 722 KiB After Width: | Height: | Size: 706 KiB |
Before Width: | Height: | Size: 724 KiB After Width: | Height: | Size: 709 KiB |
Before Width: | Height: | Size: 722 KiB After Width: | Height: | Size: 706 KiB |
Before Width: | Height: | Size: 724 KiB After Width: | Height: | Size: 709 KiB |
Before Width: | Height: | Size: 722 KiB After Width: | Height: | Size: 706 KiB |
Before Width: | Height: | Size: 724 KiB After Width: | Height: | Size: 709 KiB |
Before Width: | Height: | Size: 722 KiB After Width: | Height: | Size: 706 KiB |
@ -81,7 +81,7 @@ export const SETTINGS_MAP: SettingSection[] = [
|
||||
description:
|
||||
'Describe your product in a few sentences. This context helps our AI assistant provide relevant answers and suggestions.',
|
||||
component: <ProjectProductDescription />,
|
||||
flag: '!ENVIRONMENTS',
|
||||
flag: ['ARTIFICIAL_HOG', '!ENVIRONMENTS'],
|
||||
},
|
||||
{
|
||||
id: 'snippet',
|
||||
|
@ -74,16 +74,9 @@ export const settingsLogic = kea<settingsLogicType>([
|
||||
},
|
||||
],
|
||||
sections: [
|
||||
(s) => [s.featureFlags],
|
||||
(featureFlags): SettingSection[] => {
|
||||
const sections = SETTINGS_MAP.filter((x) => {
|
||||
const isFlagConditionMet = !x.flag
|
||||
? true // No flag condition
|
||||
: x.flag.startsWith('!')
|
||||
? !featureFlags[FEATURE_FLAGS[x.flag.slice(1)]] // Negated flag condition (!-prefixed)
|
||||
: featureFlags[FEATURE_FLAGS[x.flag]] // Regular flag condition
|
||||
return isFlagConditionMet
|
||||
})
|
||||
(s) => [s.doesMatchFlags, s.featureFlags],
|
||||
(doesMatchFlags, featureFlags): SettingSection[] => {
|
||||
const sections = SETTINGS_MAP.filter(doesMatchFlags)
|
||||
if (!featureFlags[FEATURE_FLAGS.ENVIRONMENTS]) {
|
||||
return sections
|
||||
.filter((section) => section.level !== 'project')
|
||||
@ -108,24 +101,8 @@ export const settingsLogic = kea<settingsLogicType>([
|
||||
},
|
||||
],
|
||||
settings: [
|
||||
(s) => [
|
||||
s.selectedLevel,
|
||||
s.selectedSectionId,
|
||||
s.sections,
|
||||
s.settingId,
|
||||
s.featureFlags,
|
||||
s.hasAvailableFeature,
|
||||
s.preflight,
|
||||
],
|
||||
(
|
||||
selectedLevel,
|
||||
selectedSectionId,
|
||||
sections,
|
||||
settingId,
|
||||
featureFlags,
|
||||
hasAvailableFeature,
|
||||
preflight
|
||||
): Setting[] => {
|
||||
(s) => [s.selectedLevel, s.selectedSectionId, s.sections, s.settingId, s.doesMatchFlags, s.preflight],
|
||||
(selectedLevel, selectedSectionId, sections, settingId, doesMatchFlags, preflight): Setting[] => {
|
||||
let settings: Setting[] = []
|
||||
|
||||
if (selectedSectionId) {
|
||||
@ -140,29 +117,40 @@ export const settingsLogic = kea<settingsLogicType>([
|
||||
return settings.filter((x) => x.id === settingId)
|
||||
}
|
||||
|
||||
return settings
|
||||
.filter((x) => {
|
||||
const isFlagConditionMet = !x.flag
|
||||
? true // No flag condition
|
||||
: x.flag.startsWith('!')
|
||||
? !featureFlags[FEATURE_FLAGS[x.flag.slice(1)]] // Negated flag condition (!-prefixed)
|
||||
: featureFlags[FEATURE_FLAGS[x.flag]] // Regular flag condition
|
||||
if (x.flag && x.features) {
|
||||
return x.features.some((feat) => hasAvailableFeature(feat)) || isFlagConditionMet
|
||||
} else if (x.features) {
|
||||
return x.features.some((feat) => hasAvailableFeature(feat))
|
||||
} else if (x.flag) {
|
||||
return isFlagConditionMet
|
||||
}
|
||||
|
||||
return settings.filter((x) => {
|
||||
if (!doesMatchFlags(x)) {
|
||||
return false
|
||||
}
|
||||
if (x.hideOn?.includes(Realm.Cloud) && preflight?.cloud) {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
})
|
||||
},
|
||||
],
|
||||
doesMatchFlags: [
|
||||
(s) => [s.featureFlags],
|
||||
(featureFlags) => {
|
||||
return (x: Pick<Setting, 'flag'>) => {
|
||||
if (!x.flag) {
|
||||
// No flag condition
|
||||
return true
|
||||
})
|
||||
.filter((x) => {
|
||||
if (x.hideOn?.includes(Realm.Cloud) && preflight?.cloud) {
|
||||
}
|
||||
const flagsArray = Array.isArray(x.flag) ? x.flag : [x.flag]
|
||||
for (const flagCondition of flagsArray) {
|
||||
const flag = (
|
||||
flagCondition.startsWith('!') ? flagCondition.slice(1) : flagCondition
|
||||
) as keyof typeof FEATURE_FLAGS
|
||||
let isConditionMet = featureFlags[FEATURE_FLAGS[flag]]
|
||||
if (flagCondition.startsWith('!')) {
|
||||
isConditionMet = !isConditionMet // Negated flag condition (!-prefixed)
|
||||
}
|
||||
if (!isConditionMet) {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
})
|
||||
}
|
||||
return true
|
||||
}
|
||||
},
|
||||
],
|
||||
}),
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { EitherMembershipLevel, FEATURE_FLAGS } from 'lib/constants'
|
||||
|
||||
import { AvailableFeature, Realm } from '~/types'
|
||||
import { Realm } from '~/types'
|
||||
|
||||
export type SettingsLogicProps = {
|
||||
logicKey?: string
|
||||
@ -111,21 +111,16 @@ export type Setting = {
|
||||
/**
|
||||
* Feature flag to gate the setting being shown.
|
||||
* If prefixed with !, the condition is inverted - the setting will only be shown if the is flag false.
|
||||
* When an array is provided, the setting will be shown if ALL of the conditions are met.
|
||||
*/
|
||||
flag?: FeatureFlagKey | `!${FeatureFlagKey}`
|
||||
features?: AvailableFeature[]
|
||||
flag?: FeatureFlagKey | `!${FeatureFlagKey}` | (FeatureFlagKey | `!${FeatureFlagKey}`)[]
|
||||
hideOn?: Realm[]
|
||||
}
|
||||
|
||||
export type SettingSection = {
|
||||
export interface SettingSection extends Pick<Setting, 'flag'> {
|
||||
id: SettingSectionId
|
||||
title: string
|
||||
level: SettingLevelId
|
||||
settings: Setting[]
|
||||
/**
|
||||
* Feature flag to gate the section being shown.
|
||||
* If prefixed with !, the condition is inverted - the section will only be shown if the is flag false.
|
||||
*/
|
||||
flag?: FeatureFlagKey | `!${FeatureFlagKey}`
|
||||
minimumAccessLevel?: EitherMembershipLevel
|
||||
}
|
||||
|