From 2ab99624d23306b0116b2fc38324bfaa8c038230 Mon Sep 17 00:00:00 2001 From: Thomas Heartman Date: Wed, 14 Feb 2024 10:12:19 +0900 Subject: [PATCH] feat: show env var conflicts in change requests (#6182) This PR adds showing of env variant conflicts in change requests. This is a simple solution that only compares the total state of variants. We *could* potentially do a modified version where we show each and every variant as its own property. Because variants have to be unique by name and because their names can't be changed after their creation, we could create a map of variant name to their data. image --- .../Change/StrategyChangeOverwriteWarning.tsx | 28 +++++++++++++++++-- .../Change/VariantPatch/VariantPatch.tsx | 5 ++++ .../strategy-change-diff-calculation.ts | 19 +++++++++++++ .../changeRequest/changeRequest.types.ts | 1 + 4 files changed, 51 insertions(+), 2 deletions(-) diff --git a/frontend/src/component/changeRequest/ChangeRequest/Changes/Change/StrategyChangeOverwriteWarning.tsx b/frontend/src/component/changeRequest/ChangeRequest/Changes/Change/StrategyChangeOverwriteWarning.tsx index ccae24d905..7387f22b6c 100644 --- a/frontend/src/component/changeRequest/ChangeRequest/Changes/Change/StrategyChangeOverwriteWarning.tsx +++ b/frontend/src/component/changeRequest/ChangeRequest/Changes/Change/StrategyChangeOverwriteWarning.tsx @@ -1,6 +1,7 @@ import { Box, styled } from '@mui/material'; import { useChangeRequestPlausibleContext } from 'component/changeRequest/ChangeRequestContext'; import { + IChangeRequestPatchVariant, IChangeRequestUpdateSegment, IChangeRequestUpdateStrategy, } from 'component/changeRequest/changeRequest.types'; @@ -9,10 +10,12 @@ import { ISegment } from 'interfaces/segment'; import { IFeatureStrategy } from 'interfaces/strategy'; import { ChangesThatWouldBeOverwritten, + getEnvVariantChangesThatWouldBeOverwritten, getStrategyChangesThatWouldBeOverwritten, getSegmentChangesThatWouldBeOverwritten, } from './strategy-change-diff-calculation'; import { useEffect } from 'react'; +import { IFeatureVariant } from 'interfaces/featureToggle'; const ChangesToOverwriteContainer = styled(Box)(({ theme }) => ({ color: theme.palette.warning.dark, @@ -135,13 +138,13 @@ const DetailsTable: React.FC<{ }; const OverwriteWarning: React.FC<{ - changeType: 'segment' | 'strategy'; + changeType: 'segment' | 'strategy' | 'environment variant configuration'; changesThatWouldBeOverwritten: ChangesThatWouldBeOverwritten; }> = ({ changeType, changesThatWouldBeOverwritten }) => { return (

- Heads up! The ${changeType} has been updated + Heads up! The {changeType} has been updated since you made your changes. Applying this change now would overwrite the configuration that is currently live.

@@ -157,6 +160,27 @@ const OverwriteWarning: React.FC<{ ); }; +export const EnvVariantChangesToOverwrite: React.FC<{ + currentVariants?: IFeatureVariant[]; + change: IChangeRequestPatchVariant; +}> = ({ change, currentVariants }) => { + const checkForChanges = useUiFlag('changeRequestConflictHandling'); + const changesThatWouldBeOverwritten = checkForChanges + ? getEnvVariantChangesThatWouldBeOverwritten(currentVariants, change) + : null; + + if (!changesThatWouldBeOverwritten) { + return null; + } + + return ( + + ); +}; + export const SegmentChangesToOverwrite: React.FC<{ currentSegment?: ISegment; change: IChangeRequestUpdateSegment; diff --git a/frontend/src/component/changeRequest/ChangeRequest/Changes/Change/VariantPatch/VariantPatch.tsx b/frontend/src/component/changeRequest/ChangeRequest/Changes/Change/VariantPatch/VariantPatch.tsx index 656a881f32..d216752d6e 100644 --- a/frontend/src/component/changeRequest/ChangeRequest/Changes/Change/VariantPatch/VariantPatch.tsx +++ b/frontend/src/component/changeRequest/ChangeRequest/Changes/Change/VariantPatch/VariantPatch.tsx @@ -6,6 +6,7 @@ import { TooltipLink } from 'component/common/TooltipLink/TooltipLink'; import { EnvironmentVariantsTable } from 'component/feature/FeatureView/FeatureVariants/FeatureEnvironmentVariants/EnvironmentVariantsCard/EnvironmentVariantsTable/EnvironmentVariantsTable'; import { useFeature } from 'hooks/api/getters/useFeature/useFeature'; import { ReactNode } from 'react'; +import { EnvVariantChangesToOverwrite } from '../StrategyChangeOverwriteWarning'; import { VariantDiff } from './VariantDiff'; const ChangeItemInfo = styled(Box)({ @@ -53,6 +54,10 @@ export const VariantPatch = ({ return ( + ( return null; } +export function getEnvVariantChangesThatWouldBeOverwritten( + currentVariantConfig: IFeatureVariant[] | undefined, + change: IChangeRequestPatchVariant, +): ChangesThatWouldBeOverwritten | null { + const { snapshot } = change.payload; + if (!snapshot || !currentVariantConfig) return null; + + const conflict = getChangedPropertyWithFallbacks({})( + 'variants', + currentVariantConfig, + snapshot, + change.payload.variants, + ); + + return conflict ? [conflict] : null; +} + export function getSegmentChangesThatWouldBeOverwritten( currentSegmentConfig: ISegment | undefined, change: IChangeRequestUpdateSegment, diff --git a/frontend/src/component/changeRequest/changeRequest.types.ts b/frontend/src/component/changeRequest/changeRequest.types.ts index 33dbe168ec..685070be91 100644 --- a/frontend/src/component/changeRequest/changeRequest.types.ts +++ b/frontend/src/component/changeRequest/changeRequest.types.ts @@ -218,6 +218,7 @@ export type ISegmentChange = type ChangeRequestVariantPatch = { variants: IFeatureVariant[]; + snapshot?: IFeatureVariant[]; }; type ChangeRequestEnabled = { enabled: boolean };