diff --git a/frontend/src/component/changeRequest/ChangeRequest/Changes/Change/Change.tsx b/frontend/src/component/changeRequest/ChangeRequest/Changes/Change/Change.tsx
index 0a760a9bf1..dd03080771 100644
--- a/frontend/src/component/changeRequest/ChangeRequest/Changes/Change/Change.tsx
+++ b/frontend/src/component/changeRequest/ChangeRequest/Changes/Change/Change.tsx
@@ -1,4 +1,4 @@
-import React, { FC, ReactNode } from 'react';
+import { FC, ReactNode } from 'react';
import {
hasNameField,
IChange,
@@ -20,6 +20,7 @@ import {
StrategyDeletedChange,
StrategyEditedChange,
} from './StrategyChange';
+import { VariantPatch } from './VariantPatch/VariantPatch';
const StyledSingleChangeBox = styled(Box, {
shouldForwardProp: (prop: string) => !prop.startsWith('$'),
@@ -138,6 +139,15 @@ export const Change: FC<{
>
)}
+ {change.action === 'patchVariant' && (
+
+ )}
);
diff --git a/frontend/src/component/changeRequest/ChangeRequest/Changes/Change/VariantPatch/Diff.tsx b/frontend/src/component/changeRequest/ChangeRequest/Changes/Change/VariantPatch/Diff.tsx
new file mode 100644
index 0000000000..d0caf4aaff
--- /dev/null
+++ b/frontend/src/component/changeRequest/ChangeRequest/Changes/Change/VariantPatch/Diff.tsx
@@ -0,0 +1,29 @@
+import { styled } from '@mui/material';
+import EventDiff from 'component/events/EventDiff/EventDiff';
+
+const StyledCodeSection = styled('div')(({ theme }) => ({
+ overflowX: 'auto',
+ '& code': {
+ wordWrap: 'break-word',
+ whiteSpace: 'pre-wrap',
+ fontFamily: 'monospace',
+ lineHeight: 1.5,
+ fontSize: theme.fontSizes.smallBody,
+ },
+}));
+
+interface IDiffProps {
+ preData: any;
+ data: any;
+}
+
+export const Diff = ({ preData, data }: IDiffProps) => (
+
+
+
+);
diff --git a/frontend/src/component/changeRequest/ChangeRequest/Changes/Change/VariantPatch/VariantPatch.tsx b/frontend/src/component/changeRequest/ChangeRequest/Changes/Change/VariantPatch/VariantPatch.tsx
new file mode 100644
index 0000000000..d9b1d0e335
--- /dev/null
+++ b/frontend/src/component/changeRequest/ChangeRequest/Changes/Change/VariantPatch/VariantPatch.tsx
@@ -0,0 +1,50 @@
+import { Box, styled, Typography } from '@mui/material';
+import { IChangeRequestPatchVariant } from 'component/changeRequest/changeRequest.types';
+import { useFeature } from 'hooks/api/getters/useFeature/useFeature';
+import { ReactNode } from 'react';
+import { Diff } from './Diff';
+
+export const ChangeItemCreateEditWrapper = styled(Box)(({ theme }) => ({
+ display: 'flex',
+ justifyContent: 'space-between',
+ alignItems: 'center',
+ marginBottom: theme.spacing(2),
+}));
+
+const ChangeItemInfo = styled(Box)(({ theme }) => ({
+ display: 'flex',
+ flexDirection: 'column',
+ gap: theme.spacing(1),
+}));
+
+interface IVariantPatchProps {
+ feature: string;
+ project: string;
+ environment: string;
+ change: IChangeRequestPatchVariant;
+ discard?: ReactNode;
+}
+
+export const VariantPatch = ({
+ feature,
+ project,
+ environment,
+ change,
+ discard,
+}: IVariantPatchProps) => {
+ const { feature: featureData } = useFeature(project, feature);
+
+ const preData = featureData.environments.find(
+ ({ name }) => environment === name
+ )?.variants;
+
+ return (
+
+
+ Updating variants:
+
+
+ {discard}
+
+ );
+};
diff --git a/frontend/src/component/changeRequest/changeRequest.types.ts b/frontend/src/component/changeRequest/changeRequest.types.ts
index 992cb5feca..8d9fdb49e2 100644
--- a/frontend/src/component/changeRequest/changeRequest.types.ts
+++ b/frontend/src/component/changeRequest/changeRequest.types.ts
@@ -1,3 +1,4 @@
+import { IFeatureVariant } from 'interfaces/featureToggle';
import { IFeatureStrategy } from '../../interfaces/strategy';
import { IUser } from '../../interfaces/user';
@@ -60,7 +61,8 @@ type ChangeRequestPayload =
| ChangeRequestEnabled
| ChangeRequestAddStrategy
| ChangeRequestEditStrategy
- | ChangeRequestDeleteStrategy;
+ | ChangeRequestDeleteStrategy
+ | ChangeRequestVariantPatch;
export interface IChangeRequestAddStrategy extends IChangeRequestBase {
action: 'addStrategy';
@@ -82,11 +84,21 @@ export interface IChangeRequestEnabled extends IChangeRequestBase {
payload: ChangeRequestEnabled;
}
+export interface IChangeRequestPatchVariant extends IChangeRequestBase {
+ action: 'patchVariant';
+ payload: ChangeRequestVariantPatch;
+}
+
export type IChange =
| IChangeRequestAddStrategy
| IChangeRequestDeleteStrategy
| IChangeRequestUpdateStrategy
- | IChangeRequestEnabled;
+ | IChangeRequestEnabled
+ | IChangeRequestPatchVariant;
+
+type ChangeRequestVariantPatch = {
+ variants: IFeatureVariant[];
+};
type ChangeRequestEnabled = { enabled: boolean };
@@ -106,7 +118,8 @@ export type ChangeRequestAction =
| 'updateEnabled'
| 'addStrategy'
| 'updateStrategy'
- | 'deleteStrategy';
+ | 'deleteStrategy'
+ | 'patchVariant';
export const hasNameField = (payload: unknown): payload is { name: string } =>
typeof payload === 'object' && payload !== null && 'name' in payload;
diff --git a/frontend/src/component/events/EventDiff/EventDiff.tsx b/frontend/src/component/events/EventDiff/EventDiff.tsx
index e5b46c0cea..d4f5a205dd 100644
--- a/frontend/src/component/events/EventDiff/EventDiff.tsx
+++ b/frontend/src/component/events/EventDiff/EventDiff.tsx
@@ -50,7 +50,7 @@ const EventDiff = ({ entry }: IEventDiffProps) => {
const buildDiff = (diff: any, idx: number) => {
let change;
- const key = diff.path.join('.');
+ const key = diff.path?.join('.') ?? diff.index;
if (diff.item) {
change = buildItemDiff(diff.item, key);
@@ -74,13 +74,16 @@ const EventDiff = ({ entry }: IEventDiffProps) => {
);
}
- return
{change}
;
+ return { key: key.toString(), value: {change}
};
};
let changes;
if (diffs) {
- changes = diffs.map(buildDiff);
+ changes = diffs
+ .map(buildDiff)
+ .sort((a, b) => a.key.localeCompare(b.key))
+ .map(({ value }) => value);
} else {
// Just show the data if there is no diff yet.
const data = entry.data || entry.preData;