Skip to content

Commit

Permalink
feat: show segment conflicts in crs (#6138)
Browse files Browse the repository at this point in the history
This PR updates the diff calculation to work with both strategy changes
and segment changes. It also adds the corresponding segment change
conflict overview to segment updates.

<img width="1225" alt="image"
src="https://github.com/Unleash/unleash/assets/17786332/688a57a5-5cd7-4b0a-bd1e-df63189594d8">
  • Loading branch information
thomasheartman committed Feb 9, 2024
1 parent ba2cde7 commit b77f312
Show file tree
Hide file tree
Showing 6 changed files with 309 additions and 134 deletions.
Expand Up @@ -7,6 +7,7 @@ import {
import { useSegment } from 'hooks/api/getters/useSegment/useSegment';
import { SegmentDiff, SegmentTooltipLink } from '../../SegmentTooltipLink';
import { ConstraintAccordionList } from 'component/common/ConstraintAccordion/ConstraintAccordionList/ConstraintAccordionList';
import { SegmentChangesToOverwrite } from './StrategyChangeOverwriteWarning';

const ChangeItemCreateEditWrapper = styled(Box)(({ theme }) => ({
display: 'grid',
Expand Down Expand Up @@ -77,6 +78,10 @@ export const SegmentChangeDetails: VFC<{
)}
{change.action === 'updateSegment' && (
<>
<SegmentChangesToOverwrite
currentSegment={currentSegment}
change={change}
/>
<ChangeItemCreateEditWrapper>
<ChangeItemInfo>
<Typography>Editing segment:</Typography>
Expand Down
Expand Up @@ -17,7 +17,7 @@ import { Badge } from 'component/common/Badge/Badge';
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
import { flexRow } from 'themes/themeStyles';
import { EnvironmentVariantsTable } from 'component/feature/FeatureView/FeatureVariants/FeatureEnvironmentVariants/EnvironmentVariantsCard/EnvironmentVariantsTable/EnvironmentVariantsTable';
import { ChangesToOverwrite } from './StrategyChangeOverwriteWarning';
import { StrategyChangesToOverwrite } from './StrategyChangeOverwriteWarning';

export const ChangeItemWrapper = styled(Box)({
display: 'flex',
Expand Down Expand Up @@ -210,7 +210,7 @@ export const StrategyChange: VFC<{
)}
{change.action === 'updateStrategy' && (
<>
<ChangesToOverwrite
<StrategyChangesToOverwrite
currentStrategy={currentStrategy}
change={change}
/>
Expand Down
@@ -1,12 +1,20 @@
import { Box, styled } from '@mui/material';
import { IChangeRequestUpdateStrategy } from 'component/changeRequest/changeRequest.types';
import { useChangeRequestPlausibleContext } from 'component/changeRequest/ChangeRequestContext';
import {
IChangeRequestUpdateSegment,
IChangeRequestUpdateStrategy,
} from 'component/changeRequest/changeRequest.types';
import { useUiFlag } from 'hooks/useUiFlag';
import { ISegment } from 'interfaces/segment';
import { IFeatureStrategy } from 'interfaces/strategy';
import { getChangesThatWouldBeOverwritten } from './strategy-change-diff-calculation';
import {
ChangesThatWouldBeOverwritten,
getStrategyChangesThatWouldBeOverwritten,
getSegmentChangesThatWouldBeOverwritten,
} from './strategy-change-diff-calculation';
import { useEffect } from 'react';

const ChangesToOverwriteWarning = styled(Box)(({ theme }) => ({
const ChangesToOverwriteContainer = styled(Box)(({ theme }) => ({
color: theme.palette.warning.dark,
backgroundColor: theme.palette.warning.light,
fontSize: theme.fontSizes.smallBody,
Expand Down Expand Up @@ -70,13 +78,113 @@ const OverwriteTable = styled('table')(({ theme }) => ({
},
}));

export const ChangesToOverwrite: React.FC<{
const DetailsTable: React.FC<{
changesThatWouldBeOverwritten: ChangesThatWouldBeOverwritten;
}> = ({ changesThatWouldBeOverwritten }) => {
return (
<OverwriteTable>
<thead>
<tr>
<th>Property</th>
<th>Current value</th>
<th>Value after change</th>
</tr>
</thead>

<tbody>
{changesThatWouldBeOverwritten.map(
({ property, oldValue, newValue }) => (
<tr key={property}>
<td data-column='Property'>{property}</td>
<td data-column='Current value'>
<pre>
<del>
{JSON.stringify(oldValue, null, 2)
.split('\n')
.map((line, index) => (
<code
key={`${property}${line}${index}`}
>
{`${line}\n`}
</code>
))}
</del>
</pre>
</td>
<td data-column='Value after change'>
<pre>
<ins>
{JSON.stringify(newValue, null, 2)
.split('\n')
.map((line, index) => (
<code
key={`${property}${line}${index}`}
>
{`${line}\n`}
</code>
))}
</ins>
</pre>
</td>
</tr>
),
)}
</tbody>
</OverwriteTable>
);
};

const OverwriteWarning: React.FC<{
changeType: 'segment' | 'strategy';
changesThatWouldBeOverwritten: ChangesThatWouldBeOverwritten;
}> = ({ changeType, changesThatWouldBeOverwritten }) => {
return (
<ChangesToOverwriteContainer>
<p>
<strong>Heads up!</strong> The ${changeType} has been updated
since you made your changes. Applying this change now would
overwrite the configuration that is currently live.
</p>
<details>
<summary>Changes that would be overwritten</summary>
<DetailsTable
changesThatWouldBeOverwritten={
changesThatWouldBeOverwritten
}
/>
</details>
</ChangesToOverwriteContainer>
);
};

export const SegmentChangesToOverwrite: React.FC<{
currentSegment?: ISegment;
change: IChangeRequestUpdateSegment;
}> = ({ change, currentSegment }) => {
const checkForChanges = useUiFlag('changeRequestConflictHandling');
const changesThatWouldBeOverwritten = checkForChanges
? getSegmentChangesThatWouldBeOverwritten(currentSegment, change)
: null;

if (!changesThatWouldBeOverwritten) {
return null;
}

return (
<OverwriteWarning
changeType='segment'
changesThatWouldBeOverwritten={changesThatWouldBeOverwritten}
/>
);
};

export const StrategyChangesToOverwrite: React.FC<{
currentStrategy?: IFeatureStrategy;
change: IChangeRequestUpdateStrategy;
}> = ({ change, currentStrategy }) => {
const checkForChanges = useUiFlag('changeRequestConflictHandling');
const changesThatWouldBeOverwritten = checkForChanges
? getChangesThatWouldBeOverwritten(currentStrategy, change)
? getStrategyChangesThatWouldBeOverwritten(currentStrategy, change)
: null;
const { registerWillOverwriteStrategyChanges } =
useChangeRequestPlausibleContext();
Expand All @@ -92,73 +200,9 @@ export const ChangesToOverwrite: React.FC<{
}

return (
<ChangesToOverwriteWarning>
<p>
<strong>Heads up!</strong> The strategy has been updated since
you made your changes. Applying this change now would overwrite
the configuration that is currently live.
</p>
<details>
<summary>Changes that would be overwritten</summary>

<OverwriteTable>
<thead>
<tr>
<th>Property</th>
<th>Current value</th>
<th>Value after change</th>
</tr>
</thead>

<tbody>
{changesThatWouldBeOverwritten.map(
({ property, oldValue, newValue }) => (
<tr key={property}>
<td data-column='Property'>{property}</td>
<td data-column='Current value'>
<pre>
<del>
{JSON.stringify(
oldValue,
null,
2,
)
.split('\n')
.map((line, index) => (
<code
key={`${property}${line}${index}`}
>
{`${line}\n`}
</code>
))}
</del>
</pre>
</td>
<td data-column='Value after change'>
<pre>
<ins>
{JSON.stringify(
newValue,
null,
2,
)
.split('\n')
.map((line, index) => (
<code
key={`${property}${line}${index}`}
>
{`${line}\n`}
</code>
))}
</ins>
</pre>
</td>
</tr>
),
)}
</tbody>
</OverwriteTable>
</details>
</ChangesToOverwriteWarning>
<OverwriteWarning
changeType='strategy'
changesThatWouldBeOverwritten={changesThatWouldBeOverwritten}
/>
);
};

0 comments on commit b77f312

Please sign in to comment.