mirror of
https://github.com/Unleash/unleash.git
synced 2025-05-12 01:17:04 +02:00
feat: add creation buttons to application features and strategies (#6387)

This commit is contained in:
parent
68095916e8
commit
a958797a8a
@ -1,12 +1,20 @@
|
||||
import { Box, styled } from '@mui/material';
|
||||
import { ConditionallyRender } from '../../common/ConditionallyRender/ConditionallyRender';
|
||||
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
|
||||
import { WarningAmberRounded } from '@mui/icons-material';
|
||||
import { ApplicationOverviewIssuesSchema } from 'openapi';
|
||||
import { Link } from 'react-router-dom';
|
||||
import {
|
||||
CREATE_FEATURE,
|
||||
CREATE_STRATEGY,
|
||||
} from 'component/providers/AccessProvider/permissions';
|
||||
import { useContext } from 'react';
|
||||
import AccessContext from 'contexts/AccessContext';
|
||||
|
||||
const WarningContainer = styled(Box)(({ theme }) => ({
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
alignSelf: 'stretch',
|
||||
fontSize: theme.fontSizes.smallBody,
|
||||
}));
|
||||
|
||||
const WarningHeader = styled(Box)(({ theme }) => ({
|
||||
@ -21,11 +29,7 @@ const WarningHeader = styled(Box)(({ theme }) => ({
|
||||
color: theme.palette.warning.main,
|
||||
}));
|
||||
|
||||
const SmallText = styled(Box)(({ theme }) => ({
|
||||
fontSize: theme.fontSizes.smallBody,
|
||||
}));
|
||||
|
||||
const WarningHeaderText = styled(SmallText)(({ theme }) => ({
|
||||
const WarningHeaderText = styled(Box)(({ theme }) => ({
|
||||
color: theme.palette.warning.dark,
|
||||
fontWeight: theme.fontWeight.bold,
|
||||
}));
|
||||
@ -36,7 +40,6 @@ const StyledList = styled('ul')(({ theme }) => ({
|
||||
|
||||
const StyledListElement = styled('li')(({ theme }) => ({
|
||||
fontWeight: theme.fontWeight.bold,
|
||||
fontSize: theme.fontSizes.smallBody,
|
||||
}));
|
||||
|
||||
const IssueContainer = styled(Box)(({ theme }) => ({
|
||||
@ -62,6 +65,20 @@ const IssueTextContainer = styled(Box)(({ theme }) => ({
|
||||
border: `1px solid ${theme.palette.divider}`,
|
||||
}));
|
||||
|
||||
const IssueRowContainer = styled(Box)(({ theme }) => ({
|
||||
display: 'flex',
|
||||
flexDirection: 'row',
|
||||
gap: theme.spacing(1.5),
|
||||
alignItems: 'center',
|
||||
}));
|
||||
|
||||
const StyledLink = styled(Link)(() => ({
|
||||
overflow: 'hidden',
|
||||
textOverflow: 'ellipsis',
|
||||
whiteSpace: 'nowrap',
|
||||
textDecoration: 'underline',
|
||||
}));
|
||||
|
||||
export interface IApplicationIssuesProps {
|
||||
issues: ApplicationOverviewIssuesSchema[];
|
||||
}
|
||||
@ -85,6 +102,7 @@ const resolveIssueText = (issue: ApplicationOverviewIssuesSchema) => {
|
||||
};
|
||||
|
||||
export const ApplicationIssues = ({ issues }: IApplicationIssuesProps) => {
|
||||
const { hasAccess } = useContext(AccessContext);
|
||||
return (
|
||||
<ConditionallyRender
|
||||
condition={issues.length > 0}
|
||||
@ -100,12 +118,44 @@ export const ApplicationIssues = ({ issues }: IApplicationIssuesProps) => {
|
||||
<IssueContainer>
|
||||
{issues.map((issue) => (
|
||||
<IssueTextContainer key={issue.type}>
|
||||
<SmallText>{resolveIssueText(issue)}</SmallText>
|
||||
{resolveIssueText(issue)}
|
||||
<StyledList>
|
||||
{issue.items.map((item) => (
|
||||
<StyledListElement key={item}>
|
||||
{item}
|
||||
</StyledListElement>
|
||||
<IssueRowContainer key={item}>
|
||||
<StyledListElement>
|
||||
{item}
|
||||
</StyledListElement>
|
||||
<ConditionallyRender
|
||||
condition={
|
||||
issue.type ===
|
||||
'missingFeatures' &&
|
||||
hasAccess(CREATE_FEATURE)
|
||||
}
|
||||
show={
|
||||
<StyledLink
|
||||
key={item}
|
||||
to={`/projects/default/create-toggle?name=${item}`}
|
||||
>
|
||||
Create feature flag
|
||||
</StyledLink>
|
||||
}
|
||||
/>
|
||||
<ConditionallyRender
|
||||
condition={
|
||||
issue.type ===
|
||||
'missingStrategies' &&
|
||||
hasAccess(CREATE_STRATEGY)
|
||||
}
|
||||
show={
|
||||
<StyledLink
|
||||
key={item}
|
||||
to={`/strategies/create`}
|
||||
>
|
||||
Create strategy type
|
||||
</StyledLink>
|
||||
}
|
||||
/>
|
||||
</IssueRowContainer>
|
||||
))}
|
||||
</StyledList>
|
||||
</IssueTextContainer>
|
||||
|
@ -72,3 +72,48 @@ test('Display application overview without environments', async () => {
|
||||
await screen.findByText('my-app');
|
||||
await screen.findByText('No data available.');
|
||||
});
|
||||
|
||||
test('Display application with issues', async () => {
|
||||
setupApi({
|
||||
environments: [
|
||||
{
|
||||
name: 'development',
|
||||
instanceCount: 999,
|
||||
lastSeen: new Date().toISOString(),
|
||||
sdks: ['unleash-client-node:5.5.0-beta.0'],
|
||||
},
|
||||
],
|
||||
issues: [
|
||||
{
|
||||
type: 'missingFeatures',
|
||||
items: ['feature1'],
|
||||
},
|
||||
{
|
||||
type: 'missingStrategies',
|
||||
items: ['strategy1'],
|
||||
},
|
||||
],
|
||||
featureCount: 1,
|
||||
projects: ['default'],
|
||||
});
|
||||
render(
|
||||
<Routes>
|
||||
<Route
|
||||
path={'/applications/:name'}
|
||||
element={<ApplicationOverview />}
|
||||
/>
|
||||
</Routes>,
|
||||
{
|
||||
route: '/applications/my-app',
|
||||
},
|
||||
);
|
||||
|
||||
await screen.findByText(
|
||||
'We detected 1 feature flag defined in the SDK that does not exist in Unleash',
|
||||
);
|
||||
await screen.findByText(
|
||||
'We detected 1 strategy type defined in the SDK that does not exist in Unleash',
|
||||
);
|
||||
await screen.findByText('feature1');
|
||||
await screen.findByText('strategy1');
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user