mirror of
https://github.com/Unleash/unleash.git
synced 2025-09-24 17:51:14 +02:00
chore: limit total custom strategies displayed (#10688)
https://linear.app/unleash/issue/2-3897/limit-custom-strategies-like-were-doing-with-release-templates Limits total custom strategies displayed, like we're doing for release templates, in the new "add strategy" modal. Added a more generic logic to `FeatureStrategyMenuCardsSection.tsx` so we can reuse it for both. We can also do it for other sections in the modal, but that feels like a premature optimization. These 2 categories are the ones that are user owned, and can have many items.
This commit is contained in:
parent
e98b511bb2
commit
3d9f5581d5
@ -38,6 +38,8 @@ const FILTERS = [
|
|||||||
|
|
||||||
export type StrategyFilterValue = (typeof FILTERS)[number]['value'];
|
export type StrategyFilterValue = (typeof FILTERS)[number]['value'];
|
||||||
|
|
||||||
|
const CUSTOM_STRATEGY_DISPLAY_LIMIT = 5;
|
||||||
|
|
||||||
const StyledContainer = styled(Box)(() => ({
|
const StyledContainer = styled(Box)(() => ({
|
||||||
width: '100%',
|
width: '100%',
|
||||||
display: 'flex',
|
display: 'flex',
|
||||||
@ -118,6 +120,9 @@ export const FeatureStrategyMenuCards = ({
|
|||||||
(strategy) => strategy.editable,
|
(strategy) => strategy.editable,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const customStrategyDisplayLimit =
|
||||||
|
filter === 'custom' ? 0 : CUSTOM_STRATEGY_DISPLAY_LIMIT;
|
||||||
|
|
||||||
const availableFilters = useMemo(
|
const availableFilters = useMemo(
|
||||||
() =>
|
() =>
|
||||||
FILTERS.filter(({ value }) => {
|
FILTERS.filter(({ value }) => {
|
||||||
@ -281,7 +286,11 @@ export const FeatureStrategyMenuCards = ({
|
|||||||
</FeatureStrategyMenuCardsSection>
|
</FeatureStrategyMenuCardsSection>
|
||||||
)}
|
)}
|
||||||
{shouldRender('custom') && customStrategies.length > 0 && (
|
{shouldRender('custom') && customStrategies.length > 0 && (
|
||||||
<FeatureStrategyMenuCardsSection title='Custom strategies'>
|
<FeatureStrategyMenuCardsSection
|
||||||
|
title='Custom strategies'
|
||||||
|
limit={customStrategyDisplayLimit}
|
||||||
|
viewMore={() => setFilter('custom')}
|
||||||
|
>
|
||||||
{customStrategies.map(renderStrategy)}
|
{customStrategies.map(renderStrategy)}
|
||||||
</FeatureStrategyMenuCardsSection>
|
</FeatureStrategyMenuCardsSection>
|
||||||
)}
|
)}
|
||||||
|
@ -2,7 +2,7 @@ import { useReleasePlanTemplates } from 'hooks/api/getters/useReleasePlanTemplat
|
|||||||
import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig';
|
import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig';
|
||||||
import { ReactComponent as ReleaseTemplateIcon } from 'assets/img/releaseTemplates.svg';
|
import { ReactComponent as ReleaseTemplateIcon } from 'assets/img/releaseTemplates.svg';
|
||||||
import type { IReleasePlanTemplate } from 'interfaces/releasePlans.ts';
|
import type { IReleasePlanTemplate } from 'interfaces/releasePlans.ts';
|
||||||
import { Box, Button, styled } from '@mui/material';
|
import { Box, styled } from '@mui/material';
|
||||||
import type { StrategyFilterValue } from './FeatureStrategyMenuCards.tsx';
|
import type { StrategyFilterValue } from './FeatureStrategyMenuCards.tsx';
|
||||||
import type { Dispatch, SetStateAction } from 'react';
|
import type { Dispatch, SetStateAction } from 'react';
|
||||||
import { Link as RouterLink } from 'react-router-dom';
|
import { Link as RouterLink } from 'react-router-dom';
|
||||||
@ -74,16 +74,6 @@ const StyledNoTemplatesDescription = styled('p')(({ theme }) => ({
|
|||||||
color: theme.palette.text.secondary,
|
color: theme.palette.text.secondary,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const StyledViewMoreButton = styled(Button)(({ theme }) => ({
|
|
||||||
display: 'flex',
|
|
||||||
alignItems: 'center',
|
|
||||||
justifyContent: 'center',
|
|
||||||
height: theme.spacing(10),
|
|
||||||
padding: theme.spacing(2),
|
|
||||||
border: `1px solid ${theme.palette.divider}`,
|
|
||||||
borderRadius: theme.spacing(1),
|
|
||||||
}));
|
|
||||||
|
|
||||||
const StyledLink = styled(RouterLink)({
|
const StyledLink = styled(RouterLink)({
|
||||||
textDecoration: 'none',
|
textDecoration: 'none',
|
||||||
'&:hover': {
|
'&:hover': {
|
||||||
@ -113,10 +103,9 @@ export const FeatureStrategyMenuCardsReleaseTemplates = ({
|
|||||||
|
|
||||||
const isFiltered = filter === 'releaseTemplates';
|
const isFiltered = filter === 'releaseTemplates';
|
||||||
const shouldShowHeader = !isFiltered || templates.length > 0;
|
const shouldShowHeader = !isFiltered || templates.length > 0;
|
||||||
|
const releaseTemplatesDisplayLimit = isFiltered
|
||||||
const slicedTemplates = isFiltered
|
? 0
|
||||||
? templates
|
: RELEASE_TEMPLATE_DISPLAY_LIMIT;
|
||||||
: templates.slice(0, RELEASE_TEMPLATE_DISPLAY_LIMIT);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Box>
|
<Box>
|
||||||
@ -153,8 +142,12 @@ export const FeatureStrategyMenuCardsReleaseTemplates = ({
|
|||||||
</StyledNoTemplatesBody>
|
</StyledNoTemplatesBody>
|
||||||
</StyledNoTemplatesContainer>
|
</StyledNoTemplatesContainer>
|
||||||
) : (
|
) : (
|
||||||
<FeatureStrategyMenuCardsSection>
|
<FeatureStrategyMenuCardsSection
|
||||||
{slicedTemplates.map((template) => (
|
limit={releaseTemplatesDisplayLimit}
|
||||||
|
viewMore={() => setFilter('releaseTemplates')}
|
||||||
|
viewMoreLabel='View more templates'
|
||||||
|
>
|
||||||
|
{templates.map((template) => (
|
||||||
<FeatureStrategyMenuCard
|
<FeatureStrategyMenuCard
|
||||||
key={template.id}
|
key={template.id}
|
||||||
name={template.name}
|
name={template.name}
|
||||||
@ -175,16 +168,6 @@ export const FeatureStrategyMenuCardsReleaseTemplates = ({
|
|||||||
</FeatureStrategyMenuCardAction>
|
</FeatureStrategyMenuCardAction>
|
||||||
</FeatureStrategyMenuCard>
|
</FeatureStrategyMenuCard>
|
||||||
))}
|
))}
|
||||||
{slicedTemplates.length < templates.length &&
|
|
||||||
templates.length > RELEASE_TEMPLATE_DISPLAY_LIMIT && (
|
|
||||||
<StyledViewMoreButton
|
|
||||||
variant='text'
|
|
||||||
size='small'
|
|
||||||
onClick={() => setFilter('releaseTemplates')}
|
|
||||||
>
|
|
||||||
View more templates
|
|
||||||
</StyledViewMoreButton>
|
|
||||||
)}
|
|
||||||
</FeatureStrategyMenuCardsSection>
|
</FeatureStrategyMenuCardsSection>
|
||||||
)}
|
)}
|
||||||
</Box>
|
</Box>
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { Box, styled } from '@mui/material';
|
import { Box, Button, styled } from '@mui/material';
|
||||||
import type { ReactNode } from 'react';
|
import type { ReactNode } from 'react';
|
||||||
|
|
||||||
export const StyledStrategyModalSectionHeader = styled(Box)(({ theme }) => ({
|
export const StyledStrategyModalSectionHeader = styled(Box)(({ theme }) => ({
|
||||||
@ -17,23 +17,52 @@ const StyledStrategyModalSectionGrid = styled(Box)(({ theme }) => ({
|
|||||||
width: '100%',
|
width: '100%',
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
const StyledViewMoreButton = styled(Button)(({ theme }) => ({
|
||||||
|
display: 'flex',
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'center',
|
||||||
|
height: theme.spacing(10),
|
||||||
|
padding: theme.spacing(2),
|
||||||
|
border: `1px solid ${theme.palette.divider}`,
|
||||||
|
borderRadius: theme.spacing(1),
|
||||||
|
}));
|
||||||
|
|
||||||
interface IFeatureStrategyMenuCardsSectionProps {
|
interface IFeatureStrategyMenuCardsSectionProps {
|
||||||
title?: string;
|
title?: string;
|
||||||
children: ReactNode;
|
limit?: number;
|
||||||
|
viewMore?: () => void;
|
||||||
|
viewMoreLabel?: string;
|
||||||
|
children: ReactNode[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export const FeatureStrategyMenuCardsSection = ({
|
export const FeatureStrategyMenuCardsSection = ({
|
||||||
title,
|
title,
|
||||||
|
limit,
|
||||||
|
viewMore,
|
||||||
|
viewMoreLabel = 'View more',
|
||||||
children,
|
children,
|
||||||
}: IFeatureStrategyMenuCardsSectionProps) => (
|
}: IFeatureStrategyMenuCardsSectionProps) => {
|
||||||
<Box>
|
const limitedChildren = limit ? children.slice(0, limit) : children;
|
||||||
{title && (
|
|
||||||
<StyledStrategyModalSectionHeader>
|
return (
|
||||||
{title}
|
<Box>
|
||||||
</StyledStrategyModalSectionHeader>
|
{title && (
|
||||||
)}
|
<StyledStrategyModalSectionHeader>
|
||||||
<StyledStrategyModalSectionGrid>
|
{title}
|
||||||
{children}
|
</StyledStrategyModalSectionHeader>
|
||||||
</StyledStrategyModalSectionGrid>
|
)}
|
||||||
</Box>
|
<StyledStrategyModalSectionGrid>
|
||||||
);
|
{limitedChildren}
|
||||||
|
{viewMore && limitedChildren.length < children.length && (
|
||||||
|
<StyledViewMoreButton
|
||||||
|
variant='text'
|
||||||
|
size='small'
|
||||||
|
onClick={viewMore}
|
||||||
|
>
|
||||||
|
{viewMoreLabel}
|
||||||
|
</StyledViewMoreButton>
|
||||||
|
)}
|
||||||
|
</StyledStrategyModalSectionGrid>
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user