mirror of
https://github.com/Unleash/unleash.git
synced 2025-07-31 13:47:02 +02:00
feat: feature links section (#9915)
This commit is contained in:
parent
b322afb097
commit
2b73b17579
@ -1,5 +1,12 @@
|
|||||||
import { type FC, useState } from 'react';
|
import { type FC, useState } from 'react';
|
||||||
import { styled } from '@mui/material';
|
import {
|
||||||
|
Button,
|
||||||
|
List,
|
||||||
|
ListItemButton,
|
||||||
|
ListItemIcon,
|
||||||
|
ListItemText,
|
||||||
|
styled,
|
||||||
|
} from '@mui/material';
|
||||||
import { useNavigate } from 'react-router-dom';
|
import { useNavigate } from 'react-router-dom';
|
||||||
import { FeatureArchiveDialog } from 'component/common/FeatureArchiveDialog/FeatureArchiveDialog';
|
import { FeatureArchiveDialog } from 'component/common/FeatureArchiveDialog/FeatureArchiveDialog';
|
||||||
import { FeatureArchiveNotAllowedDialog } from 'component/common/FeatureArchiveDialog/FeatureArchiveNotAllowedDialog';
|
import { FeatureArchiveNotAllowedDialog } from 'component/common/FeatureArchiveDialog/FeatureArchiveNotAllowedDialog';
|
||||||
@ -15,7 +22,14 @@ import { capitalizeFirst } from 'utils/capitalizeFirst';
|
|||||||
import { Collaborators } from './Collaborators';
|
import { Collaborators } from './Collaborators';
|
||||||
import { EnvironmentVisibilityMenu } from './EnvironmentVisibilityMenu/EnvironmentVisibilityMenu';
|
import { EnvironmentVisibilityMenu } from './EnvironmentVisibilityMenu/EnvironmentVisibilityMenu';
|
||||||
import { Truncator } from 'component/common/Truncator/Truncator';
|
import { Truncator } from 'component/common/Truncator/Truncator';
|
||||||
import type { IFeatureToggle } from '../../../../../interfaces/featureToggle';
|
import type {
|
||||||
|
FeatureLink,
|
||||||
|
IFeatureToggle,
|
||||||
|
} from '../../../../../interfaces/featureToggle';
|
||||||
|
import AddIcon from '@mui/icons-material/Add';
|
||||||
|
import { useUiFlag } from 'hooks/useUiFlag';
|
||||||
|
import { Badge } from 'component/common/Badge/Badge';
|
||||||
|
import LinkIcon from '@mui/icons-material/Link';
|
||||||
|
|
||||||
const StyledMetaDataContainer = styled('div')(({ theme }) => ({
|
const StyledMetaDataContainer = styled('div')(({ theme }) => ({
|
||||||
padding: theme.spacing(3),
|
padding: theme.spacing(3),
|
||||||
@ -29,6 +43,7 @@ const StyledMetaDataContainer = styled('div')(({ theme }) => ({
|
|||||||
[theme.breakpoints.down('md')]: {
|
[theme.breakpoints.down('md')]: {
|
||||||
width: '100%',
|
width: '100%',
|
||||||
},
|
},
|
||||||
|
marginBottom: theme.spacing(2),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const StyledTitle = styled('h2')(({ theme }) => ({
|
const StyledTitle = styled('h2')(({ theme }) => ({
|
||||||
@ -65,6 +80,10 @@ export const StyledMetaDataItemValue = styled('div')(({ theme }) => ({
|
|||||||
gap: theme.spacing(1),
|
gap: theme.spacing(1),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
export const StyledListItemIcon = styled(ListItemIcon)(({ theme }) => ({
|
||||||
|
minWidth: theme.spacing(5),
|
||||||
|
}));
|
||||||
|
|
||||||
type FeatureOverviewMetaDataProps = {
|
type FeatureOverviewMetaDataProps = {
|
||||||
hiddenEnvironments?: string[];
|
hiddenEnvironments?: string[];
|
||||||
onEnvironmentVisibilityChange?: (environment: string) => void;
|
onEnvironmentVisibilityChange?: (environment: string) => void;
|
||||||
@ -72,6 +91,74 @@ type FeatureOverviewMetaDataProps = {
|
|||||||
onChange: () => void;
|
onChange: () => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const FeatureLinks: FC<{ links: FeatureLink[] }> = ({ links }) => {
|
||||||
|
return links.length === 0 ? (
|
||||||
|
<StyledMetaDataContainer>
|
||||||
|
<StyledTitle>
|
||||||
|
You can now add links{' '}
|
||||||
|
<Badge color='success' sx={{ ml: 1 }}>
|
||||||
|
New
|
||||||
|
</Badge>
|
||||||
|
</StyledTitle>
|
||||||
|
<StyledMetaDataItem>
|
||||||
|
Gather relevant links for external resources such as issue
|
||||||
|
trackers, code repositories or analytics tooling
|
||||||
|
</StyledMetaDataItem>
|
||||||
|
<div>
|
||||||
|
<Button
|
||||||
|
size='small'
|
||||||
|
variant='text'
|
||||||
|
startIcon={<AddIcon />}
|
||||||
|
onClick={() => {}}
|
||||||
|
>
|
||||||
|
Add link
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</StyledMetaDataContainer>
|
||||||
|
) : (
|
||||||
|
<StyledMetaDataContainer>
|
||||||
|
<StyledTitle>Resources</StyledTitle>
|
||||||
|
<List>
|
||||||
|
{links.map((link) => (
|
||||||
|
<ListItemButton
|
||||||
|
component='a'
|
||||||
|
href={link.url}
|
||||||
|
target='_blank'
|
||||||
|
rel='noopener noreferrer'
|
||||||
|
>
|
||||||
|
<StyledListItemIcon>
|
||||||
|
<LinkIcon color='primary' />
|
||||||
|
</StyledListItemIcon>
|
||||||
|
<ListItemText
|
||||||
|
primary={link.title}
|
||||||
|
secondary={link.url}
|
||||||
|
secondaryTypographyProps={{
|
||||||
|
sx: {
|
||||||
|
overflow: 'hidden',
|
||||||
|
textOverflow: 'ellipsis',
|
||||||
|
whiteSpace: 'nowrap',
|
||||||
|
display: 'block',
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</ListItemButton>
|
||||||
|
))}
|
||||||
|
</List>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<Button
|
||||||
|
size='small'
|
||||||
|
variant='text'
|
||||||
|
startIcon={<AddIcon />}
|
||||||
|
onClick={() => {}}
|
||||||
|
>
|
||||||
|
Add link
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</StyledMetaDataContainer>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
const FeatureOverviewMetaData: FC<FeatureOverviewMetaDataProps> = ({
|
const FeatureOverviewMetaData: FC<FeatureOverviewMetaDataProps> = ({
|
||||||
hiddenEnvironments,
|
hiddenEnvironments,
|
||||||
onEnvironmentVisibilityChange,
|
onEnvironmentVisibilityChange,
|
||||||
@ -89,8 +176,13 @@ const FeatureOverviewMetaData: FC<FeatureOverviewMetaDataProps> = ({
|
|||||||
|
|
||||||
const showDependentFeatures = useShowDependentFeatures(project);
|
const showDependentFeatures = useShowDependentFeatures(project);
|
||||||
|
|
||||||
|
const featureLinksEnabled = useUiFlag('featureLinks');
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
{featureLinksEnabled ? (
|
||||||
|
<FeatureLinks links={feature.links || []} />
|
||||||
|
) : null}
|
||||||
<StyledMetaDataContainer>
|
<StyledMetaDataContainer>
|
||||||
<div>
|
<div>
|
||||||
<StyledTitle>Flag details</StyledTitle>
|
<StyledTitle>Flag details</StyledTitle>
|
||||||
|
@ -49,6 +49,8 @@ export type CollaboratorData = {
|
|||||||
users: Collaborator[];
|
users: Collaborator[];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type FeatureLink = { url: string; title: string | null; id: string };
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @deprecated use FeatureSchema from openapi
|
* @deprecated use FeatureSchema from openapi
|
||||||
*/
|
*/
|
||||||
@ -76,6 +78,7 @@ export interface IFeatureToggle {
|
|||||||
imageUrl: string;
|
imageUrl: string;
|
||||||
};
|
};
|
||||||
collaborators?: CollaboratorData;
|
collaborators?: CollaboratorData;
|
||||||
|
links?: FeatureLink[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IDependency {
|
export interface IDependency {
|
||||||
|
@ -95,6 +95,7 @@ export type UiFlags = {
|
|||||||
flagsReleaseManagementUI?: boolean;
|
flagsReleaseManagementUI?: boolean;
|
||||||
cleanupReminder?: boolean;
|
cleanupReminder?: boolean;
|
||||||
registerFrontendClient?: boolean;
|
registerFrontendClient?: boolean;
|
||||||
|
featureLinks?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
export interface IVersionInfo {
|
export interface IVersionInfo {
|
||||||
|
@ -61,6 +61,7 @@ process.nextTick(async () => {
|
|||||||
cleanupReminder: true,
|
cleanupReminder: true,
|
||||||
strictSchemaValidation: true,
|
strictSchemaValidation: true,
|
||||||
registerFrontendClient: true,
|
registerFrontendClient: true,
|
||||||
|
featureLinks: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
authentication: {
|
authentication: {
|
||||||
|
Loading…
Reference in New Issue
Block a user