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:
parent
63b569981d
commit
da06cfd374
@ -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>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
@ -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', () => {
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user