diff --git a/frontend/src/component/feature/FeatureView/FeatureOverview/FeatureOverviewSidePanel/FeatureOverviewSidePanelEnvironmentSwitches/FeatureOverviewSidePanelEnvironmentSwitch/FeatureOverviewSidePanelEnvironmentSwitch.tsx b/frontend/src/component/feature/FeatureView/FeatureOverview/FeatureOverviewSidePanel/FeatureOverviewSidePanelEnvironmentSwitches/FeatureOverviewSidePanelEnvironmentSwitch/FeatureOverviewSidePanelEnvironmentSwitch.tsx index 7cff86af28..972bafe917 100644 --- a/frontend/src/component/feature/FeatureView/FeatureOverview/FeatureOverviewSidePanel/FeatureOverviewSidePanelEnvironmentSwitches/FeatureOverviewSidePanelEnvironmentSwitch/FeatureOverviewSidePanelEnvironmentSwitch.tsx +++ b/frontend/src/component/feature/FeatureView/FeatureOverview/FeatureOverviewSidePanel/FeatureOverviewSidePanelEnvironmentSwitches/FeatureOverviewSidePanelEnvironmentSwitch/FeatureOverviewSidePanelEnvironmentSwitch.tsx @@ -4,8 +4,7 @@ import { useRequiredPathParam } from 'hooks/useRequiredPathParam'; import { styled } from '@mui/material'; import StringTruncator from 'component/common/StringTruncator/StringTruncator'; import { FeatureOverviewSidePanelEnvironmentHider } from './FeatureOverviewSidePanelEnvironmentHider'; -import { FeatureToggleSwitch } from 'component/project/Project/ProjectFeatureToggles/FeatureToggleSwitch/FeatureToggleSwitch'; -import { useMemo } from 'react'; +import { FeatureToggleSwitch } from 'component/project/Project/ProjectFeatureToggles/FeatureToggleSwitch/LegacyFeatureToggleSwitch'; const StyledContainer = styled('div')(({ theme }) => ({ marginLeft: theme.spacing(-1.5), @@ -59,20 +58,6 @@ export const FeatureOverviewSidePanelEnvironmentSwitch = ({ if (callback) callback(); }; - const featureEnvironment = feature?.environments?.find( - (env) => env.name === environment.name, - ); - - const hasStrategies = - featureEnvironment?.strategies && - featureEnvironment?.strategies?.length > 0; - - const hasEnabledStrategies = - hasStrategies && - featureEnvironment?.strategies?.some( - (strategy) => strategy.disabled !== true, - ); - return ( @@ -80,12 +65,9 @@ export const FeatureOverviewSidePanelEnvironmentSwitch = ({ featureId={feature.name} projectId={projectId} environmentName={environment.name} - type={featureEnvironment?.type || ''} onToggle={handleToggle} onError={showInfoBox} value={enabled} - hasStrategies={hasStrategies} - hasEnabledStrategies={hasEnabledStrategies} /> {children ?? defaultContent} diff --git a/frontend/src/component/project/Project/ProjectFeatureToggles/FeatureToggleSwitch/LegacyFeatureToggleSwitch.tsx b/frontend/src/component/project/Project/ProjectFeatureToggles/FeatureToggleSwitch/LegacyFeatureToggleSwitch.tsx index 9c97a86adc..fb92c9aec4 100644 --- a/frontend/src/component/project/Project/ProjectFeatureToggles/FeatureToggleSwitch/LegacyFeatureToggleSwitch.tsx +++ b/frontend/src/component/project/Project/ProjectFeatureToggles/FeatureToggleSwitch/LegacyFeatureToggleSwitch.tsx @@ -39,7 +39,7 @@ interface IFeatureToggleSwitchProps { } /** - * @deprecated + * @deprecated remove when flag `featureSwitchRefactor` is removed */ export const FeatureToggleSwitch: VFC = ({ projectId, diff --git a/frontend/src/component/project/Project/ProjectFeatureToggles/LegacyProjectFeatureToggles.tsx b/frontend/src/component/project/Project/ProjectFeatureToggles/LegacyProjectFeatureToggles.tsx index 5f81e662a2..2b00ce23c1 100644 --- a/frontend/src/component/project/Project/ProjectFeatureToggles/LegacyProjectFeatureToggles.tsx +++ b/frontend/src/component/project/Project/ProjectFeatureToggles/LegacyProjectFeatureToggles.tsx @@ -112,7 +112,7 @@ const defaultSort: SortingRule & { } = { id: 'createdAt' }; /** - * @deprecated + * @deprecated remove when flag `featureSwitchRefactor` is removed */ export const ProjectFeatureToggles = ({ features, diff --git a/frontend/src/component/project/Project/ProjectOverview.tsx b/frontend/src/component/project/Project/ProjectOverview.tsx index f735b82184..11f07e532e 100644 --- a/frontend/src/component/project/Project/ProjectOverview.tsx +++ b/frontend/src/component/project/Project/ProjectOverview.tsx @@ -4,11 +4,13 @@ import useProject, { } from 'hooks/api/getters/useProject/useProject'; import { Box, styled } from '@mui/material'; import { ProjectFeatureToggles as LegacyProjectFeatureToggles } from './ProjectFeatureToggles/LegacyProjectFeatureToggles'; +import { ProjectFeatureToggles } from './ProjectFeatureToggles/ProjectFeatureToggles'; import ProjectInfo from './ProjectInfo/ProjectInfo'; import { usePageTitle } from 'hooks/usePageTitle'; import { useRequiredPathParam } from 'hooks/useRequiredPathParam'; import { useLastViewedProject } from 'hooks/useLastViewedProject'; import { ProjectStats } from './ProjectStats/ProjectStats'; +import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; const refreshInterval = 15 * 1000; @@ -59,11 +61,24 @@ const ProjectOverview = () => { - ( + + )} + elseShow={() => ( + + )} /> diff --git a/frontend/src/interfaces/uiConfig.ts b/frontend/src/interfaces/uiConfig.ts index e227653e3d..7cf4cc83b8 100644 --- a/frontend/src/interfaces/uiConfig.ts +++ b/frontend/src/interfaces/uiConfig.ts @@ -72,6 +72,7 @@ export type UiFlags = { internalMessageBanners?: boolean; disableEnvsOnRevive?: boolean; playgroundImprovements?: boolean; + featureSwitchRefactor?: boolean; }; export interface IVersionInfo { diff --git a/src/lib/features/feature-toggle/feature-toggle-strategies-store.ts b/src/lib/features/feature-toggle/feature-toggle-strategies-store.ts index 30110f7b1a..e1628fea94 100644 --- a/src/lib/features/feature-toggle/feature-toggle-strategies-store.ts +++ b/src/lib/features/feature-toggle/feature-toggle-strategies-store.ts @@ -601,15 +601,17 @@ class FeatureStrategiesStore implements IFeatureStrategiesStore { ]; } - selectColumns = [ - ...selectColumns, - this.db.raw( - 'EXISTS (SELECT 1 FROM feature_strategies WHERE feature_strategies.feature_name = features.name AND feature_strategies.environment = feature_environments.environment) as has_strategies', - ), - this.db.raw( - 'EXISTS (SELECT 1 FROM feature_strategies WHERE feature_strategies.feature_name = features.name AND feature_strategies.environment = feature_environments.environment AND (feature_strategies.disabled IS NULL OR feature_strategies.disabled = false)) as has_enabled_strategies', - ), - ]; + if (this.flagResolver.isEnabled('featureSwitchRefactor')) { + selectColumns = [ + ...selectColumns, + this.db.raw( + 'EXISTS (SELECT 1 FROM feature_strategies WHERE feature_strategies.feature_name = features.name AND feature_strategies.environment = feature_environments.environment) as has_strategies', + ), + this.db.raw( + 'EXISTS (SELECT 1 FROM feature_strategies WHERE feature_strategies.feature_name = features.name AND feature_strategies.environment = feature_environments.environment AND (feature_strategies.disabled IS NULL OR feature_strategies.disabled = false)) as has_enabled_strategies', + ), + ]; + } query = query.select(selectColumns); const rows = await query; diff --git a/src/lib/types/experimental.ts b/src/lib/types/experimental.ts index e663acb270..940798c343 100644 --- a/src/lib/types/experimental.ts +++ b/src/lib/types/experimental.ts @@ -38,7 +38,8 @@ export type IFlagKey = | 'internalMessageBanner' | 'separateAdminClientApi' | 'disableEnvsOnRevive' - | 'playgroundImprovements'; + | 'playgroundImprovements' + | 'featureSwitchRefactor'; export type IFlags = Partial<{ [key in IFlagKey]: boolean | Variant }>; @@ -178,6 +179,10 @@ const flags: IFlags = { process.env.UNLEASH_EXPERIMENTAL_PLAYGROUND_IMPROVEMENTS, false, ), + featureSwitchRefactor: parseEnvVarBoolean( + process.env.UNLEASH_EXPERIMENTAL_FEATURE_SWITCH_REFACTOR, + false, + ), }; export const defaultExperimentalOptions: IExperimentalOptions = { diff --git a/src/lib/types/model.ts b/src/lib/types/model.ts index 8c84a8cd63..58c85e2dfe 100644 --- a/src/lib/types/model.ts +++ b/src/lib/types/model.ts @@ -194,8 +194,8 @@ export interface IEnvironmentBase { export interface IEnvironmentOverview extends IEnvironmentBase { variantCount: number; - hasStrategies: boolean; - hasEnabledStrategies: boolean; + hasStrategies?: boolean; + hasEnabledStrategies?: boolean; } export interface IFeatureOverview { diff --git a/src/server-dev.ts b/src/server-dev.ts index 63d3c6eed8..efed982833 100644 --- a/src/server-dev.ts +++ b/src/server-dev.ts @@ -49,6 +49,7 @@ process.nextTick(async () => { useLastSeenRefactor: true, separateAdminClientApi: true, playgroundImprovements: true, + featureSwitchRefactor: true, }, }, authentication: {