Skip to content

Commit 2b73b17

Browse files
authored
feat: feature links section (#9915)
1 parent b322afb commit 2b73b17

File tree

4 files changed

+99
-2
lines changed

4 files changed

+99
-2
lines changed

frontend/src/component/feature/FeatureView/FeatureOverview/FeatureOverviewMetaData/FeatureOverviewMetaData.tsx

+94-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,12 @@
11
import { type FC, useState } from 'react';
2-
import { styled } from '@mui/material';
2+
import {
3+
Button,
4+
List,
5+
ListItemButton,
6+
ListItemIcon,
7+
ListItemText,
8+
styled,
9+
} from '@mui/material';
310
import { useNavigate } from 'react-router-dom';
411
import { FeatureArchiveDialog } from 'component/common/FeatureArchiveDialog/FeatureArchiveDialog';
512
import { FeatureArchiveNotAllowedDialog } from 'component/common/FeatureArchiveDialog/FeatureArchiveNotAllowedDialog';
@@ -15,7 +22,14 @@ import { capitalizeFirst } from 'utils/capitalizeFirst';
1522
import { Collaborators } from './Collaborators';
1623
import { EnvironmentVisibilityMenu } from './EnvironmentVisibilityMenu/EnvironmentVisibilityMenu';
1724
import { Truncator } from 'component/common/Truncator/Truncator';
18-
import type { IFeatureToggle } from '../../../../../interfaces/featureToggle';
25+
import type {
26+
FeatureLink,
27+
IFeatureToggle,
28+
} from '../../../../../interfaces/featureToggle';
29+
import AddIcon from '@mui/icons-material/Add';
30+
import { useUiFlag } from 'hooks/useUiFlag';
31+
import { Badge } from 'component/common/Badge/Badge';
32+
import LinkIcon from '@mui/icons-material/Link';
1933

2034
const StyledMetaDataContainer = styled('div')(({ theme }) => ({
2135
padding: theme.spacing(3),
@@ -29,6 +43,7 @@ const StyledMetaDataContainer = styled('div')(({ theme }) => ({
2943
[theme.breakpoints.down('md')]: {
3044
width: '100%',
3145
},
46+
marginBottom: theme.spacing(2),
3247
}));
3348

3449
const StyledTitle = styled('h2')(({ theme }) => ({
@@ -65,13 +80,85 @@ export const StyledMetaDataItemValue = styled('div')(({ theme }) => ({
6580
gap: theme.spacing(1),
6681
}));
6782

83+
export const StyledListItemIcon = styled(ListItemIcon)(({ theme }) => ({
84+
minWidth: theme.spacing(5),
85+
}));
86+
6887
type FeatureOverviewMetaDataProps = {
6988
hiddenEnvironments?: string[];
7089
onEnvironmentVisibilityChange?: (environment: string) => void;
7190
feature: IFeatureToggle;
7291
onChange: () => void;
7392
};
7493

94+
const FeatureLinks: FC<{ links: FeatureLink[] }> = ({ links }) => {
95+
return links.length === 0 ? (
96+
<StyledMetaDataContainer>
97+
<StyledTitle>
98+
You can now add links{' '}
99+
<Badge color='success' sx={{ ml: 1 }}>
100+
New
101+
</Badge>
102+
</StyledTitle>
103+
<StyledMetaDataItem>
104+
Gather relevant links for external resources such as issue
105+
trackers, code repositories or analytics tooling
106+
</StyledMetaDataItem>
107+
<div>
108+
<Button
109+
size='small'
110+
variant='text'
111+
startIcon={<AddIcon />}
112+
onClick={() => {}}
113+
>
114+
Add link
115+
</Button>
116+
</div>
117+
</StyledMetaDataContainer>
118+
) : (
119+
<StyledMetaDataContainer>
120+
<StyledTitle>Resources</StyledTitle>
121+
<List>
122+
{links.map((link) => (
123+
<ListItemButton
124+
component='a'
125+
href={link.url}
126+
target='_blank'
127+
rel='noopener noreferrer'
128+
>
129+
<StyledListItemIcon>
130+
<LinkIcon color='primary' />
131+
</StyledListItemIcon>
132+
<ListItemText
133+
primary={link.title}
134+
secondary={link.url}
135+
secondaryTypographyProps={{
136+
sx: {
137+
overflow: 'hidden',
138+
textOverflow: 'ellipsis',
139+
whiteSpace: 'nowrap',
140+
display: 'block',
141+
},
142+
}}
143+
/>
144+
</ListItemButton>
145+
))}
146+
</List>
147+
148+
<div>
149+
<Button
150+
size='small'
151+
variant='text'
152+
startIcon={<AddIcon />}
153+
onClick={() => {}}
154+
>
155+
Add link
156+
</Button>
157+
</div>
158+
</StyledMetaDataContainer>
159+
);
160+
};
161+
75162
const FeatureOverviewMetaData: FC<FeatureOverviewMetaDataProps> = ({
76163
hiddenEnvironments,
77164
onEnvironmentVisibilityChange,
@@ -89,8 +176,13 @@ const FeatureOverviewMetaData: FC<FeatureOverviewMetaDataProps> = ({
89176

90177
const showDependentFeatures = useShowDependentFeatures(project);
91178

179+
const featureLinksEnabled = useUiFlag('featureLinks');
180+
92181
return (
93182
<>
183+
{featureLinksEnabled ? (
184+
<FeatureLinks links={feature.links || []} />
185+
) : null}
94186
<StyledMetaDataContainer>
95187
<div>
96188
<StyledTitle>Flag details</StyledTitle>

frontend/src/interfaces/featureToggle.ts

+3
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ export type CollaboratorData = {
4949
users: Collaborator[];
5050
};
5151

52+
export type FeatureLink = { url: string; title: string | null; id: string };
53+
5254
/**
5355
* @deprecated use FeatureSchema from openapi
5456
*/
@@ -76,6 +78,7 @@ export interface IFeatureToggle {
7678
imageUrl: string;
7779
};
7880
collaborators?: CollaboratorData;
81+
links?: FeatureLink[];
7982
}
8083

8184
export interface IDependency {

frontend/src/interfaces/uiConfig.ts

+1
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ export type UiFlags = {
9595
flagsReleaseManagementUI?: boolean;
9696
cleanupReminder?: boolean;
9797
registerFrontendClient?: boolean;
98+
featureLinks?: boolean;
9899
};
99100

100101
export interface IVersionInfo {

src/server-dev.ts

+1
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ process.nextTick(async () => {
6161
cleanupReminder: true,
6262
strictSchemaValidation: true,
6363
registerFrontendClient: true,
64+
featureLinks: true,
6465
},
6566
},
6667
authentication: {

0 commit comments

Comments
 (0)