diff --git a/frontend/src/component/project/Project/ProjectFeatureToggles/ProjectFeatureToggles.tsx b/frontend/src/component/project/Project/ProjectFeatureToggles/ProjectFeatureToggles.tsx index 95e5c76076..6dda035cf0 100644 --- a/frontend/src/component/project/Project/ProjectFeatureToggles/ProjectFeatureToggles.tsx +++ b/frontend/src/component/project/Project/ProjectFeatureToggles/ProjectFeatureToggles.tsx @@ -374,6 +374,10 @@ export const ProjectFeatureToggles = ({ enabled: thisEnv?.enabled || false, variantCount: thisEnv?.variantCount || 0, lastSeenAt: thisEnv?.lastSeenAt, + type: thisEnv?.type, + hasStrategies: thisEnv?.hasStrategies, + hasEnabledStrategies: + thisEnv?.hasEnabledStrategies, }, ]; }), diff --git a/frontend/src/interfaces/featureToggle.ts b/frontend/src/interfaces/featureToggle.ts index e9102e3dd1..8c64b94050 100644 --- a/frontend/src/interfaces/featureToggle.ts +++ b/frontend/src/interfaces/featureToggle.ts @@ -17,6 +17,9 @@ export interface IEnvironments { enabled: boolean; variantCount: number; lastSeenAt?: string | null; + type?: string; + hasStrategies?: boolean; + hasEnabledStrategies?: boolean; } export interface IFeatureToggle { 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 65808ba36e..e76a166156 100644 --- a/src/lib/features/feature-toggle/feature-toggle-strategies-store.ts +++ b/src/lib/features/feature-toggle/feature-toggle-strategies-store.ts @@ -479,6 +479,8 @@ class FeatureStrategiesStore implements IFeatureStrategiesStore { sortOrder: r.environment_sort_order, variantCount: r.variants?.length || 0, lastSeenAt: r.env_last_seen_at, + hasStrategies: r.has_strategies, + hasEnabledStrategies: r.has_enabled_strategies, }; } @@ -546,7 +548,18 @@ class FeatureStrategiesStore implements IFeatureStrategiesStore { 'feature_environments.environment', 'environments.name', ) - .leftJoin('feature_tag as ft', 'ft.feature_name', 'features.name'); + .leftJoin('feature_tag as ft', 'ft.feature_name', 'features.name') + .leftJoin('feature_strategies', function () { + this.on( + 'feature_strategies.feature_name', + '=', + 'features.name', + ).andOn( + 'feature_strategies.environment', + '=', + 'feature_environments.environment', + ); + }); if (this.flagResolver.isEnabled('useLastSeenRefactor')) { query.leftJoin( @@ -599,12 +612,21 @@ 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', + ), + ]; + query = query.select(selectColumns); const rows = await query; if (rows.length > 0) { const overview = this.getFeatureOverviewData(getUniqueRows(rows)); - return sortEnvironments(overview); } return []; diff --git a/src/lib/openapi/spec/feature-environment-schema.ts b/src/lib/openapi/spec/feature-environment-schema.ts index 110140db5e..d776169e89 100644 --- a/src/lib/openapi/spec/feature-environment-schema.ts +++ b/src/lib/openapi/spec/feature-environment-schema.ts @@ -71,6 +71,15 @@ export const featureEnvironmentSchema = { description: 'The date when metrics where last collected for the feature environment', }, + hasStrategies: { + type: 'boolean', + description: 'Whether the feature has any strategies defined.', + }, + hasEnabledStrategies: { + type: 'boolean', + description: + 'Whether the feature has any enabled strategies defined.', + }, }, components: { schemas: { diff --git a/src/lib/types/model.ts b/src/lib/types/model.ts index 735b69c803..8c84a8cd63 100644 --- a/src/lib/types/model.ts +++ b/src/lib/types/model.ts @@ -194,6 +194,8 @@ export interface IEnvironmentBase { export interface IEnvironmentOverview extends IEnvironmentBase { variantCount: number; + hasStrategies: boolean; + hasEnabledStrategies: boolean; } export interface IFeatureOverview {