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

chore: add feature configuration based on addConfiguration flag

This commit is contained in:
Nuno Góis 2025-07-28 16:17:22 +01:00
parent 0a9d6437c5
commit cd16a1dfe4
No known key found for this signature in database
GPG Key ID: 71ECC689F1091765
7 changed files with 149 additions and 122 deletions

View File

@ -27,7 +27,10 @@ const CardContent = styled('div')(({ theme }) => ({
const HoverButtonsContainer = styled('div')(({ theme }) => ({
position: 'absolute',
right: theme.spacing(2),
background: theme.palette.background.paper,
padding: theme.spacing(1),
top: theme.spacing(1),
right: theme.spacing(1),
display: 'flex',
gap: theme.spacing(1),
opacity: 0,

View File

@ -75,9 +75,10 @@ export const FeatureStrategyMenu = ({
usePendingChangeRequests(projectId);
const { refetch } = useReleasePlans(projectId, featureId, environmentId);
const { addReleasePlanToFeature } = useReleasePlansApi();
const { isOss } = useUiConfig();
const { isEnterprise } = useUiConfig();
const addConfigurationEnabled = useUiFlag('addConfiguration');
const releasePlansEnabled = useUiFlag('releasePlans');
const displayReleasePlanButton = !isOss() && releasePlansEnabled;
const displayReleasePlanButton = isEnterprise() && releasePlansEnabled;
const crProtected =
releasePlansEnabled && isChangeRequestConfigured(environmentId);
@ -161,56 +162,81 @@ export const FeatureStrategyMenu = ({
return (
<StyledStrategyMenu onClick={(event) => event.stopPropagation()}>
{displayReleasePlanButton ? (
{addConfigurationEnabled ? (
<PermissionButton
data-testid='ADD_TEMPLATE_BUTTON'
data-testid='ADD_STRATEGY_BUTTON'
permission={CREATE_FEATURE_STRATEGY}
projectId={projectId}
environmentId={environmentId}
onClick={openReleasePlans}
onClick={openMoreStrategies}
aria-labelledby={dialogId}
variant='outlined'
variant={variant}
sx={{ minWidth: matchWidth ? '282px' : 'auto' }}
disabled={Boolean(disableReason)}
tooltipProps={{
title: disableReason ? disableReason : undefined,
}}
>
Use template
Add configuration
</PermissionButton>
) : null}
) : (
<>
{displayReleasePlanButton ? (
<PermissionButton
data-testid='ADD_TEMPLATE_BUTTON'
permission={CREATE_FEATURE_STRATEGY}
projectId={projectId}
environmentId={environmentId}
onClick={openReleasePlans}
aria-labelledby={dialogId}
variant='outlined'
sx={{ minWidth: matchWidth ? '282px' : 'auto' }}
disabled={Boolean(disableReason)}
tooltipProps={{
title: disableReason
? disableReason
: undefined,
}}
>
Use template
</PermissionButton>
) : null}
<PermissionButton
data-testid='ADD_STRATEGY_BUTTON'
permission={CREATE_FEATURE_STRATEGY}
projectId={projectId}
environmentId={environmentId}
onClick={openDefaultStrategyCreationModal}
aria-labelledby={dialogId}
variant={variant}
sx={{ minWidth: matchWidth ? '282px' : 'auto' }}
disabled={Boolean(disableReason)}
tooltipProps={{
title: disableReason ? disableReason : undefined,
}}
>
{label}
</PermissionButton>
<PermissionButton
data-testid='ADD_STRATEGY_BUTTON'
permission={CREATE_FEATURE_STRATEGY}
projectId={projectId}
environmentId={environmentId}
onClick={openDefaultStrategyCreationModal}
aria-labelledby={dialogId}
variant={variant}
sx={{ minWidth: matchWidth ? '282px' : 'auto' }}
disabled={Boolean(disableReason)}
tooltipProps={{
title: disableReason ? disableReason : undefined,
}}
>
{label}
</PermissionButton>
<StyledAdditionalMenuButton
permission={CREATE_FEATURE_STRATEGY}
projectId={projectId}
environmentId={environmentId}
onClick={openMoreStrategies}
variant='outlined'
hideLockIcon
disabled={Boolean(disableReason)}
tooltipProps={{
title: disableReason ? disableReason : 'More strategies',
}}
>
<MoreVert />
</StyledAdditionalMenuButton>
<StyledAdditionalMenuButton
permission={CREATE_FEATURE_STRATEGY}
projectId={projectId}
environmentId={environmentId}
onClick={openMoreStrategies}
variant='outlined'
hideLockIcon
disabled={Boolean(disableReason)}
tooltipProps={{
title: disableReason
? disableReason
: 'More strategies',
}}
>
<MoreVert />
</StyledAdditionalMenuButton>
</>
)}
<Dialog
open={isStrategyMenuDialogOpen}
onClose={onClose}

View File

@ -1,11 +1,4 @@
import {
Link,
styled,
Typography,
Box,
IconButton,
Tooltip,
} from '@mui/material';
import { Link, styled, Typography, Box, IconButton } from '@mui/material';
import { useStrategies } from 'hooks/api/getters/useStrategies/useStrategies';
import { FeatureStrategyMenuCard } from '../FeatureStrategyMenuCard/FeatureStrategyMenuCard.tsx';
import { useReleasePlanTemplates } from 'hooks/api/getters/useReleasePlanTemplates/useReleasePlanTemplates';
@ -13,10 +6,10 @@ import { FeatureReleasePlanCard } from '../FeatureReleasePlanCard/FeatureRelease
import type { IReleasePlanTemplate } from 'interfaces/releasePlans';
import { useNavigate } from 'react-router-dom';
import CloseIcon from '@mui/icons-material/Close';
import InfoOutlinedIcon from '@mui/icons-material/InfoOutlined';
import FactCheckOutlinedIcon from '@mui/icons-material/FactCheckOutlined';
import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig.ts';
import { useUiFlag } from 'hooks/useUiFlag.ts';
import { HelpIcon } from 'component/common/HelpIcon/HelpIcon.tsx';
interface IFeatureStrategyMenuCardsProps {
projectId: string;
@ -78,11 +71,6 @@ const SectionTitle = styled(Box)(({ theme }) => ({
width: '100%',
}));
const StyledInfoIcon = styled(InfoOutlinedIcon)(({ theme }) => ({
fontSize: theme.typography.body2.fontSize,
color: theme.palette.text.secondary,
}));
const StyledIcon = styled('span')(({ theme }) => ({
width: theme.spacing(3),
'& > svg': {
@ -162,55 +150,51 @@ export const FeatureStrategyMenuCards = ({
return null;
}
if (!templates.length) {
return (
<EmptyStateContainer>
<EmptyStateTitle>
<StyledIcon>
<FactCheckOutlinedIcon />
</StyledIcon>
Create your own release templates
</EmptyStateTitle>
<EmptyStateDescription>
Standardize your rollouts and save time by reusing
predefined strategies. Find release templates in the
side menu under{' '}
<ClickableBoldText
onClick={() => navigate('/release-templates')}
>
Configure &gt; Release templates
</ClickableBoldText>
</EmptyStateDescription>
</EmptyStateContainer>
);
}
return (
<Box>
<SectionTitle>
<Typography color='inherit' variant='body2'>
Apply a release template
Release templates
</Typography>
<Tooltip
title='Use a predefined template to roll out features to users'
arrow
>
<StyledInfoIcon />
</Tooltip>
<HelpIcon
tooltip='Use a predefined template to roll out features to users'
size='16px'
/>
</SectionTitle>
<GridSection>
{templates.map((template) => (
<CardWrapper key={template.id}>
<FeatureReleasePlanCard
template={template}
onClick={() => onAddReleasePlan(template)}
onPreviewClick={() =>
onReviewReleasePlan(template)
}
/>
</CardWrapper>
))}
</GridSection>
{!templates.length ? (
<EmptyStateContainer>
<EmptyStateTitle>
<StyledIcon>
<FactCheckOutlinedIcon />
</StyledIcon>
Create your own release templates
</EmptyStateTitle>
<EmptyStateDescription>
Standardize your rollouts and save time by reusing
predefined strategies. Find release templates in the
side menu under{' '}
<ClickableBoldText
onClick={() => navigate('/release-templates')}
>
Configure &gt; Release templates
</ClickableBoldText>
</EmptyStateDescription>
</EmptyStateContainer>
) : (
<GridSection>
{templates.map((template) => (
<CardWrapper key={template.id}>
<FeatureReleasePlanCard
template={template}
onClick={() => onAddReleasePlan(template)}
onPreviewClick={() =>
onReviewReleasePlan(template)
}
/>
</CardWrapper>
))}
</GridSection>
)}
</Box>
);
};
@ -219,7 +203,7 @@ export const FeatureStrategyMenuCards = ({
<GridContainer>
<TitleRow>
<TitleText variant='h2'>
{onlyReleasePlans ? 'Select template' : 'Select strategy'}
{onlyReleasePlans ? 'Select template' : 'Add configuration'}
</TitleText>
<IconButton
size='small'
@ -238,14 +222,12 @@ export const FeatureStrategyMenuCards = ({
<Box>
<SectionTitle>
<Typography color='inherit' variant='body2'>
Pre-defined strategy types
Standard strategies
</Typography>
<Tooltip
title='Select a starting setup, and customize the strategy to your need with targeting and variants'
arrow
>
<StyledInfoIcon />
</Tooltip>
<HelpIcon
tooltip='Select a starting setup, then customize your strategy with targeting and variants'
size='16px'
/>
</SectionTitle>
<GridSection>
<CardWrapper key={defaultStrategy.name}>
@ -278,12 +260,10 @@ export const FeatureStrategyMenuCards = ({
<Typography color='inherit' variant='body2'>
Custom strategies
</Typography>
<Tooltip
title='Custom strategies you have defined in Unleash'
arrow
>
<StyledInfoIcon />
</Tooltip>
<HelpIcon
tooltip='Custom strategies you have defined in Unleash'
size='16px'
/>
</SectionTitle>
<GridSection>
{customStrategies.map((strategy) => (

View File

@ -2,6 +2,8 @@ import type { FC } from 'react';
import { styled, Link } from '@mui/material';
import type { Link as RouterLink } from 'react-router-dom';
import { RELEASE_TEMPLATE_FEEDBACK } from 'constants/links';
import { useUiFlag } from 'hooks/useUiFlag';
import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig';
const StyledLink = styled(Link<typeof RouterLink | 'a'>)(({ theme }) => ({
display: 'flex',
@ -13,14 +15,23 @@ const StyledLink = styled(Link<typeof RouterLink | 'a'>)(({ theme }) => ({
marginRight: 'auto',
}));
export const ReleaseTemplatesFeedback: FC = () => (
<StyledLink
component='a'
href={RELEASE_TEMPLATE_FEEDBACK}
underline='hover'
rel='noopener noreferrer'
target='_blank'
>
Give feedback to release templates
</StyledLink>
);
export const ReleaseTemplatesFeedback: FC = () => {
const { isEnterprise } = useUiConfig();
const releaseTemplatesEnabled = useUiFlag('releasePlans');
if (!isEnterprise() || !releaseTemplatesEnabled) {
return null;
}
return (
<StyledLink
component='a'
href={RELEASE_TEMPLATE_FEEDBACK}
underline='hover'
rel='noopener noreferrer'
target='_blank'
>
Give feedback to release templates
</StyledLink>
);
};

View File

@ -95,6 +95,7 @@ export type UiFlags = {
timestampsInChangeRequestTimeline?: boolean;
reportUnknownFlags?: boolean;
lifecycleGraphs?: boolean;
addConfiguration?: boolean;
};
export interface IVersionInfo {

View File

@ -65,7 +65,8 @@ export type IFlagKey =
| 'paygInstanceStatsEvents'
| 'timestampsInChangeRequestTimeline'
| 'lifecycleGraphs'
| 'githubAuth';
| 'githubAuth'
| 'addConfiguration';
export type IFlags = Partial<{ [key in IFlagKey]: boolean | Variant }>;
@ -305,6 +306,10 @@ const flags: IFlags = {
process.env.UNLEASH_EXPERIMENTAL_GITHUB_AUTH,
false,
),
addConfiguration: parseEnvVarBoolean(
process.env.UNLEASH_EXPERIMENTAL_ADD_CONFIGURATION,
false,
),
};
export const defaultExperimentalOptions: IExperimentalOptions = {

View File

@ -61,6 +61,7 @@ process.nextTick(async () => {
paygTrialEvents: true,
timestampsInChangeRequestTimeline: true,
lifecycleGraphs: true,
addConfiguration: true,
},
},
authentication: {