Skip to content

Commit

Permalink
feat: show strategies used by segments (#5407)
Browse files Browse the repository at this point in the history
This PR displays change request usage of segments when such usage is
returned from the API. It expects at least #5406 to have been merged
before it can be merged.


![image](https://github.com/Unleash/unleash/assets/17786332/c74bb1c9-07f9-4bca-95bb-4ca020398444)
  • Loading branch information
thomasheartman authored Nov 27, 2023
1 parent 20bfa73 commit b021e7c
Show file tree
Hide file tree
Showing 4 changed files with 168 additions and 21 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,10 @@ export const SegmentDelete = ({
onClose,
onRemove,
}: ISegmentDeleteProps) => {
const { strategies, loading } = useStrategiesBySegment(segment.id);
const canDeleteSegment = strategies?.length === 0;

const { strategies, changeRequestStrategies, loading } =
useStrategiesBySegment(segment.id);
const canDeleteSegment =
strategies?.length === 0 && changeRequestStrategies?.length === 0;
if (loading) {
return null;
}
Expand All @@ -42,6 +43,7 @@ export const SegmentDelete = ({
open={open}
onClose={onClose}
strategies={strategies}
changeRequestStrategies={changeRequestStrategies}
/>
}
/>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import React from 'react';
import { render } from 'utils/testRenderer';
import { screen } from '@testing-library/react';
import { SegmentDeleteUsedSegment } from './SegmentDeleteUsedSegment';

describe('SegmentDeleteUsedSegment', () => {
it('should link to change requests for change request strategies', async () => {
const projectId = 'project1';

const crStrategies = [
{
projectId,
featureName: 'feature1',
strategyName: 'flexible rollout',
environment: 'default',
changeRequest: { id: 1, title: null },
},
{
projectId,
featureName: 'feature1',
strategyName: 'flexible rollout',
environment: 'default',
changeRequest: { id: 2, title: 'My cool CR' },
},
];

render(
<SegmentDeleteUsedSegment
changeRequestStrategies={crStrategies}
segment={{
id: 1,
name: 'segment',
description: 'description',
project: projectId,
constraints: [],
createdAt: '',
createdBy: '',
}}
open={true}
strategies={[]}
onClose={() => {}}
/>,
);

const links = await screen.findAllByRole('link');
expect(links).toHaveLength(crStrategies.length);

const [link1, link2] = links;

expect(link1).toHaveTextContent('#1');
expect(link1).toHaveAccessibleDescription('Change request 1');
expect(link1).toHaveAttribute(
'href',
`/projects/${projectId}/change-requests/1`,
);
expect(link2).toHaveTextContent('#2 (My cool CR)');
expect(link2).toHaveAccessibleDescription('Change request 2');
expect(link2).toHaveAttribute(
'href',
`/projects/${projectId}/change-requests/2`,
);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@ import { Link } from 'react-router-dom';
import { formatEditStrategyPath } from 'component/feature/FeatureStrategy/FeatureStrategyEdit/FeatureStrategyEdit';
import { formatStrategyName } from 'utils/strategyNames';
import { styled } from '@mui/material';
import {
ChangeRequestNewStrategy,
ChangeRequestStrategy,
ChangeRequestUpdatedStrategy,
} from 'hooks/api/getters/useStrategiesBySegment/useStrategiesBySegment';
import { sortStrategiesByFeature } from './sort-strategies';

const StyledUl = styled('ul')({
marginBottom: 0,
Expand All @@ -21,14 +27,29 @@ interface ISegmentDeleteUsedSegmentProps {
open: boolean;
onClose: () => void;
strategies: IFeatureStrategy[] | undefined;
changeRequestStrategies: ChangeRequestStrategy[] | undefined;
}

export const formatChangeRequestPath = (
projectId: string,
changeRequestId: number,
): string => {
return `/projects/${projectId}/change-requests/${changeRequestId}`;
};

export const SegmentDeleteUsedSegment = ({
segment,
open,
onClose,
strategies,
changeRequestStrategies,
}: ISegmentDeleteUsedSegmentProps) => {
const sortedStrategies = sortStrategiesByFeature<
IFeatureStrategy,
ChangeRequestUpdatedStrategy,
ChangeRequestNewStrategy
>(strategies ?? [], changeRequestStrategies ?? []);

return (
<Dialogue
title="You can't delete a segment that's currently in use"
Expand All @@ -41,32 +62,74 @@ export const SegmentDeleteUsedSegment = ({
<strong>{segment.name}</strong> segment for their strategies:
</p>
<StyledUl>
{strategies?.map((strategy) => (
<li key={strategy.id}>
<StyledLink
to={formatEditStrategyPath(
strategy.projectId!,
strategy.featureName!,
strategy.environment!,
strategy.id,
)}
target='_blank'
rel='noopener noreferrer'
>
{strategy.featureName!}{' '}
{formatStrategyNameParens(strategy)}
</StyledLink>
</li>
))}
{sortedStrategies.map((strategy, index) =>
strategyListItem(strategy, index),
)}
</StyledUl>
</Dialogue>
);
};

const formatStrategyNameParens = (strategy: IFeatureStrategy): string => {
const formatStrategyNameParens = (strategy: {
strategyName?: string;
}): string => {
if (!strategy.strategyName) {
return '';
}

return `(${formatStrategyName(strategy.strategyName)})`;
};

const strategyListItem = (
strategy:
| IFeatureStrategy
| ChangeRequestUpdatedStrategy
| ChangeRequestNewStrategy,
index: number,
) => {
const isChangeRequest = (
strategy: IFeatureStrategy | ChangeRequestStrategy,
): strategy is ChangeRequestStrategy => 'changeRequest' in strategy;

if (isChangeRequest(strategy)) {
const { id, title } = strategy.changeRequest;

const text = title ? `#${id} (${title})` : `#${id}`;
return (
<li key={`#${strategy.changeRequest.id}@${index}`}>
<p>
{strategy.featureName}{' '}
{`${formatStrategyNameParens(
strategy,
)} — in change request `}

<StyledLink
to={formatChangeRequestPath(strategy.projectId, id)}
target='_blank'
rel='noopener noreferrer'
title={`Change request ${id}`}
>
{text}
</StyledLink>
</p>
</li>
);
} else {
return (
<li key={strategy.id}>
<StyledLink
to={formatEditStrategyPath(
strategy.projectId!,
strategy.featureName!,
strategy.environment!,
strategy.id,
)}
target='_blank'
rel='noopener noreferrer'
>
{strategy.featureName!} {formatStrategyNameParens(strategy)}
</StyledLink>
</li>
);
}
};
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,26 @@ import handleErrorResponses from '../httpErrorResponseHandler';
import { IFeatureStrategy } from 'interfaces/strategy';
import { useConditionalSWR } from '../useConditionalSWR/useConditionalSWR';

export type ChangeRequestInfo = { id: number; title: string | null };
export type ChangeRequestNewStrategy = {
projectId: string;
featureName: string;
strategyName: string;
environment: string;
changeRequest: ChangeRequestInfo;
};

export type ChangeRequestUpdatedStrategy = ChangeRequestNewStrategy & {
id: string;
};

export type ChangeRequestStrategy =
| ChangeRequestNewStrategy
| ChangeRequestUpdatedStrategy;

export interface IUseStrategiesBySegmentOutput {
strategies: IFeatureStrategy[];
changeRequestStrategies: ChangeRequestStrategy[];
refetchUsedSegments: () => void;
loading: boolean;
error?: Error;
Expand All @@ -26,6 +44,7 @@ export const useStrategiesBySegment = (

return {
strategies: data?.strategies || [],
changeRequestStrategies: data?.changeRequestStrategies || [],
refetchUsedSegments,
loading: !error && !data,
error,
Expand Down

0 comments on commit b021e7c

Please sign in to comment.