Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add PERSISTED_FEATURE_FLAGS env #5273

Merged
merged 7 commits into from
Jul 22, 2021
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions frontend/src/layout/navigation/TopNavigation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ import { CreateInviteModalWithButton } from 'scenes/organization/Settings/Create
import { preflightLogic } from 'scenes/PreflightCheck/logic'
import { billingLogic } from 'scenes/billing/billingLogic'
import { featureFlagLogic } from 'lib/logic/featureFlagLogic'
import { Environments } from 'lib/constants'
import { Environments, FEATURE_FLAGS } from 'lib/constants'
import { ProfilePicture } from 'lib/components/ProfilePicture'

export function WhoAmI({ user }: { user: UserType }): JSX.Element {
Expand Down Expand Up @@ -294,7 +294,7 @@ export function TopNavigation(): JSX.Element {
</div>
{user && (
<div>
{featureFlags['test-environment-3149'] && (
{featureFlags[FEATURE_FLAGS.TEST_ENVIRONMENT] && (
<div className="global-environment-switch">
<label
htmlFor="global-environment-switch"
Expand Down
4 changes: 2 additions & 2 deletions frontend/src/layout/navigation/navigationLogic.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { organizationLogic } from 'scenes/organizationLogic'
import dayjs from 'dayjs'
import { eventUsageLogic } from 'lib/utils/eventUsageLogic'
import { preflightLogic } from 'scenes/PreflightCheck/logic'
import { Environments, ENVIRONMENT_LOCAL_STORAGE_KEY } from 'lib/constants'
import { Environments, ENVIRONMENT_LOCAL_STORAGE_KEY, FEATURE_FLAGS } from 'lib/constants'
import { featureFlagLogic } from 'lib/logic/featureFlagLogic'

type WarningType =
Expand Down Expand Up @@ -187,7 +187,7 @@ export const navigationLogic = kea<navigationLogicType<WarningType>>({
events: ({ actions }) => ({
afterMount: () => {
const notSharedDashboard = location.pathname.indexOf('shared_dashboard') > -1 ? false : true
if (notSharedDashboard && featureFlagLogic.values.featureFlags['test-environment-3149']) {
if (notSharedDashboard && featureFlagLogic.values.featureFlags[FEATURE_FLAGS.TEST_ENVIRONMENT]) {
const localStorageValue =
window.localStorage.getItem(ENVIRONMENT_LOCAL_STORAGE_KEY) || Environments.PRODUCTION
actions.setFilteredEnvironment(localStorageValue, true)
Expand Down
4 changes: 4 additions & 0 deletions frontend/src/lib/constants.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -226,8 +226,12 @@ export const WEBHOOK_SERVICES: Record<string, string> = {
}

export const FEATURE_FLAGS = {
TEST_ENVIRONMENT: 'test-environment-3149',
PAPERCUPS_ENABLED: 'papercups-enabled',
INGESTION_GRID: 'ingestion-grid-exp-3',
PROJECT_HOME: 'project-home-exp-5',
FORMULAS: '3275-formulas',
TRAILING_WAU_MAU: '3638-trailing-wau-mau',
EVENT_COLUMN_CONFIG: '4141-event-columns',
NPS_PROMPT: '4562-nps',
INGESTION_TAXONOMY: '4267-event-property-taxonomy',
Expand Down
18 changes: 13 additions & 5 deletions frontend/src/lib/logic/featureFlagLogic.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import { kea } from 'kea'
import { featureFlagLogicType } from './featureFlagLogicType'
import posthog from 'posthog-js'
import { getAppContext } from 'lib/utils/getAppContext'

type FeatureFlagsSet = {
[flag: string]: boolean
Expand All @@ -21,17 +22,24 @@ function notifyFlagIfNeeded(flag: string, flagState: boolean): void {
}
}

function getPersistedFeatureFlags(): FeatureFlagsSet {
const persistedFeatureFlags = getAppContext()?.persist_feature_flags || []
return Object.fromEntries(persistedFeatureFlags.map((f) => [f, true]))
}

function spyOnFeatureFlags(featureFlags: FeatureFlagsSet): FeatureFlagsSet {
const combinedFlags = { ...featureFlags, ...getPersistedFeatureFlags() }

if (typeof window.Proxy !== 'undefined') {
return new Proxy(
{},
{
get(_, flag) {
if (flag === 'toJSON') {
return JSON.stringify(featureFlags)
return () => combinedFlags
paolodamico marked this conversation as resolved.
Show resolved Hide resolved
}
const flagString = flag.toString()
const flagState = !!featureFlags[flagString]
const flagState = !!combinedFlags[flagString]
notifyFlagIfNeeded(flagString, flagState)
return flagState
},
Expand All @@ -40,11 +48,11 @@ function spyOnFeatureFlags(featureFlags: FeatureFlagsSet): FeatureFlagsSet {
} else {
// Fallback for IE11. Won't track "false" results. ¯\_(ツ)_/¯
const flags: FeatureFlagsSet = {}
for (const flag of Object.keys(featureFlags)) {
for (const flag of Object.keys(combinedFlags)) {
Object.defineProperty(flags, flag, {
get: function () {
if (flag === 'toJSON') {
return JSON.stringify(featureFlags)
return () => combinedFlags
}
notifyFlagIfNeeded(flag, true)
return true
Expand All @@ -62,7 +70,7 @@ export const featureFlagLogic = kea<featureFlagLogicType<FeatureFlagsSet>>({

reducers: {
featureFlags: [
{} as FeatureFlagsSet,
getPersistedFeatureFlags(),
{ persist: true },
{
setFeatureFlags: (_, { featureFlags }) => {
Expand Down
4 changes: 2 additions & 2 deletions frontend/src/lib/utils.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { CustomerServiceOutlined, ExclamationCircleOutlined } from '@ant-design/
import { featureFlagLogic } from './logic/featureFlagLogic'
import { open } from '@papercups-io/chat-widget'
import posthog from 'posthog-js'
import { WEBHOOK_SERVICES } from 'lib/constants'
import { FEATURE_FLAGS, WEBHOOK_SERVICES } from 'lib/constants'
import { KeyMappingInterface } from 'lib/components/PropertyKeyInfo'
import { AlignType } from 'rc-trigger/lib/interface'

Expand Down Expand Up @@ -121,7 +121,7 @@ export function errorToast(title?: string, message?: string, errorDetail?: strin
*/

const handleHelp = (): void => {
const papercupsOn = featureFlagLogic.values.featureFlags['papercups-enabled']
const papercupsOn = featureFlagLogic.values.featureFlags[FEATURE_FLAGS.PAPERCUPS_ENABLED]
if (papercupsOn) {
open()
} else {
Expand Down
3 changes: 2 additions & 1 deletion frontend/src/scenes/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import { BackTo } from 'lib/components/BackTo'
import { Papercups } from 'lib/components/Papercups'
import { appLogicType } from './AppType'
import { models } from '~/models'
import { FEATURE_FLAGS } from 'lib/constants'

export const appLogic = kea<appLogicType>({
actions: {
Expand Down Expand Up @@ -91,7 +92,7 @@ function AppScene(): JSX.Element | null {
const essentialElements = (
// Components that should always be mounted inside Layout
<>
{featureFlags['papercups-enabled'] && <Papercups />}
{featureFlags[FEATURE_FLAGS.PAPERCUPS_ENABLED] && <Papercups />}
<ToastContainer autoClose={8000} transition={Slide} position="top-right" />
</>
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -351,7 +351,7 @@ function MathSelector({

let math_entries = EVENT_MATH_ENTRIES

if (!featureFlags['3638-trailing-wau-mau'] || !preflight?.is_clickhouse_enabled) {
if (!featureFlags[FEATURE_FLAGS.TRAILING_WAU_MAU] || !preflight?.is_clickhouse_enabled) {
math_entries = math_entries.filter((item) => item[0] !== 'weekly_active' && item[0] !== 'monthly_active')
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import { InsightTitle } from '../InsightTitle'
import { InsightActionBar } from '../InsightActionBar'
import { BaseTabProps } from 'scenes/insights/Insights'
import { GlobalFiltersTitle } from 'scenes/insights/common'
import { FEATURE_FLAGS } from 'lib/constants'

export interface TrendTabProps extends BaseTabProps {
view: string
Expand All @@ -40,7 +41,7 @@ export function TrendTab({ view, annotationsToCreate }: TrendTabProps): JSX.Elem
const isSmallScreen = screens.xs || (screens.sm && !screens.md)
const formulaAvailable =
(!filters.insight || filters.insight === ViewType.TRENDS) &&
featureFlags['3275-formulas'] &&
featureFlags[FEATURE_FLAGS.FORMULAS] &&
preflight?.is_clickhouse_enabled
const formulaEnabled = (filters.events?.length || 0) + (filters.actions?.length || 0) > 1

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export function TestAccountFilter({
const hasFilters = (currentTeam?.test_account_filters || []).length > 0
//const { featureFlags } = useValues(featureFlagLogic)

//return featureFlags['test-environment-3149'] ? null : (
//return featureFlags[FEATURE_FLAGS.TEST_ENVIRONMENT] ? null : (
return (
<Tooltip
title={
Expand Down
1 change: 1 addition & 0 deletions frontend/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -974,6 +974,7 @@ export type EventOrPropType = EventDefinition & PropertyDefinition
export interface AppContext {
current_user: UserType | null
preflight: PreflightStatus
persist_feature_flags?: string[]
paolodamico marked this conversation as resolved.
Show resolved Hide resolved
}

export type StoredMetricMathOperations = 'max' | 'min' | 'sum'
8 changes: 8 additions & 0 deletions posthog/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,14 @@ def get_list(text: str) -> List[str]:
("️WARNING! E2E_TESTING is set to `True`. This is a security vulnerability unless you are running tests.")
)

# These flags will be force-enabled on the frontend **in addition to** flags from `/decide`
# The features here are released, but the flags are just not yet removed from the code.
PERSIST_FEATURE_FLAGS = get_list(os.getenv("PERSIST_FEATURE_FLAGS", "")) or [
paolodamico marked this conversation as resolved.
Show resolved Hide resolved
"4267-taxonomic-property-filter",
"4535-funnel-bar-viz",
"save-cohort-on-modal",
]

SELF_CAPTURE = get_from_env("SELF_CAPTURE", DEBUG, type_cast=str_to_bool)
SHELL_PLUS_PRINT_SQL = get_from_env("PRINT_SQL", False, type_cast=str_to_bool)
USE_PRECALCULATED_CH_COHORT_PEOPLE = not TEST
Expand Down
6 changes: 5 additions & 1 deletion posthog/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,11 @@ def render_template(template_name: str, request: HttpRequest, context: Dict = {}
from posthog.api.user import UserSerializer
from posthog.views import preflight_check

posthog_app_context: Dict = {"current_user": None, "preflight": json.loads(preflight_check(request).getvalue())}
posthog_app_context: Dict = {
"current_user": None,
"preflight": json.loads(preflight_check(request).getvalue()),
"persist_feature_flags": settings.PERSIST_FEATURE_FLAGS,
}

if request.user.pk:
user = UserSerializer(request.user, context={"request": request}, many=False)
Expand Down