1
0
mirror of https://github.com/Unleash/unleash.git synced 2025-08-27 13:49:10 +02:00

feat: impl 1

This commit is contained in:
Thomas Heartman 2023-11-23 14:50:50 +01:00
parent 63b569981d
commit da06cfd374
No known key found for this signature in database
GPG Key ID: BD1F880DAED1EE78
3 changed files with 85 additions and 153 deletions

View File

@ -7,8 +7,11 @@ import { formatStrategyName } from 'utils/strategyNames';
import { styled } from '@mui/material';
import {
ChangeRequestInfo,
ChangeRequestNewStrategy,
ChangeRequestStrategy,
ChangeRequestUpdatedStrategy,
} from 'hooks/api/getters/useStrategiesBySegment/useStrategiesBySegment';
import { sortStrategiesByFeature } from './sort-strategies';
const StyledUl = styled('ul')({
marginBottom: 0,
@ -42,109 +45,11 @@ export const SegmentDeleteUsedSegment = ({
strategies,
changeRequestStrategies,
}: ISegmentDeleteUsedSegmentProps) => {
// three kinds:
// 1. strategies without crs
// 2. crs without strategies
// 3. strategies with crs
// create a layered dictionary:
// { featureName: { existingStrategies: { ...strategy, changeRequests: [crs] }, newStrategies: [crs] }
const flagDict: {
[key: string]: {
existingStrategies: {
[key: string]:
| {
strategy?: IFeatureStrategy;
changeRequests: ChangeRequestInfo[];
}
| {
strategy: IFeatureStrategy;
changeRequests?: ChangeRequestInfo[];
};
};
newStrategies: ChangeRequestStrategy[];
};
} = Object.fromEntries(
(strategies ?? []).map((strategy) => [
strategy.featureName!,
{
existingStrategies: {
[strategy.id]: {
strategy: strategy,
},
},
newStrategies: [],
},
]),
const sortedStrategies = sortStrategiesByFeature(
strategies ?? [],
changeRequestStrategies ?? [],
);
for (const crStrategy of changeRequestStrategies ?? []) {
const { featureName } = crStrategy;
const isExistingStrategy = 'id' in crStrategy;
if (isExistingStrategy) {
const { id } = crStrategy;
const existingEntry = flagDict[featureName]?.existingStrategies[id];
if (existingEntry) {
existingEntry.changeRequests = crStrategy.changeRequests;
} else {
if (!flagDict[featureName]) {
flagDict[featureName] = {
existingStrategies: {
[id]: {
changeRequests: crStrategy.changeRequests,
},
},
newStrategies: [],
};
} else {
flagDict[featureName].existingStrategies[
id
].changeRequests = {
crStrategy.changeRequests,
};
}
}
}
}
console.log(JSON.stringify(flagDict, null, 2));
// group by flag name
const features = (strategies ?? []).reduce((acc, strategy) => {
if (!acc[strategy.featureName!]) {
acc[strategy.featureName!] = [strategy];
} else {
acc[strategy.featureName!].push(strategy);
}
return acc;
}, {} as { [key: string]: IFeatureStrategy[] });
// can we turn strategies into strategies with optional CRs? Also, CR title?
const existingStrategies: {
[key: string]: IFeatureStrategy & {
changeRequests?: ChangeRequestInfo[];
};
} = Object.fromEntries((strategies ?? []).map((s) => [s.id, s]));
const { existing, notListed } = (changeRequestStrategies ?? []).reduce(
(acc, strategy) => {
if ('id' in strategy && strategy.id in existingStrategies) {
existingStrategies[strategy.id].changeRequests =
strategy.changeRequests;
} else {
acc.notListed.push(strategy);
}
return acc;
},
{ existing: [], notListed: [] },
);
console.log(existing, notListed);
return (
<Dialogue
title="You can't delete a segment that's currently in use"
@ -157,30 +62,9 @@ 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>
))}
{changeRequestStrategies?.map((strategy, index) => (
<li key={'id' in strategy ? strategy.id : index}>
{strategy.featureName}{' '}
{formatStrategyNameParens(strategy)} - used in change
request(s): {formatChangeRequestLinks(strategy)}
</li>
))}
{sortedStrategies.map((strategy, index) =>
strategyListItem(strategy, index),
)}
</StyledUl>
</Dialogue>
);
@ -196,31 +80,80 @@ const formatStrategyNameParens = (strategy: {
return `(${formatStrategyName(strategy.strategyName)})`;
};
const formatChangeRequestLinks = ({
projectId,
changeRequests,
}: ChangeRequestStrategy) => {
const makeLink = ({ id, title }: ChangeRequestInfo) => {
// const formatChangeRequestLinks = ({ projectId }: ChangeRequestStrategy) => {
// const makeLink = ({ id, title }: ChangeRequestInfo) => {
// const text = title ? `#${id} (${title})` : `#${id}`;
// return (
// <StyledLink
// key={id}
// to={formatChangeRequestPath(projectId, id)}
// target='_blank'
// rel='noopener noreferrer'
// >
// {text}
// </StyledLink>
// );
// };
// if (changeRequests.length < 2) {
// return changeRequests.map(makeLink);
// } else {
// const sorted = [...changeRequests].sort((a, b) => a.id - b.id);
// const last = sorted.at(-1)!;
// const first = sorted.slice(0, -1);
// return `${first.map(makeLink).join(', ')} and ${makeLink(last)}`;
// }
// };
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 (
<StyledLink
key={id}
to={formatChangeRequestPath(projectId, id)}
target='_blank'
rel='noopener noreferrer'
>
{text}
</StyledLink>
<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'
>
{text}
</StyledLink>
</p>
</li>
);
};
if (changeRequests.length < 2) {
return changeRequests.map(makeLink);
} else {
const sorted = [...changeRequests].sort((a, b) => a.id - b.id);
const last = sorted.at(-1)!;
const first = sorted.slice(0, -1);
return `${first.map(makeLink).join(', ')} and ${makeLink(last)}`;
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>
);
}
};

View File

@ -1,7 +1,4 @@
import {
sortAndFlattenStrategies,
sortStrategiesByFeature,
} from './sort-strategies';
import { sortStrategiesByFeature } from './sort-strategies';
describe('sorting strategies by feature', () => {
test('strategies with the same id are sorted: existing first, then change requests', () => {

View File

@ -6,7 +6,7 @@ import { IFeatureStrategy } from 'interfaces/strategy';
import { useConditionalSWR } from '../useConditionalSWR/useConditionalSWR';
export type ChangeRequestInfo = { id: number; title: string | null };
type ChangeRequestNewStrategy = {
export type ChangeRequestNewStrategy = {
projectId: string;
featureName: string;
strategyName: string;
@ -14,7 +14,9 @@ type ChangeRequestNewStrategy = {
changeRequest: ChangeRequestInfo;
};
type ChangeRequestUpdatedStrategy = ChangeRequestNewStrategy & { id: string };
export type ChangeRequestUpdatedStrategy = ChangeRequestNewStrategy & {
id: string;
};
export type ChangeRequestStrategy =
| ChangeRequestNewStrategy