From 2b73b17579d25ce5fff9b9e2dbf04717587a4efa Mon Sep 17 00:00:00 2001 From: Mateusz Kwasniewski Date: Wed, 7 May 2025 11:35:41 +0200 Subject: [PATCH] feat: feature links section (#9915) --- .../FeatureOverviewMetaData.tsx | 96 ++++++++++++++++++- frontend/src/interfaces/featureToggle.ts | 3 + frontend/src/interfaces/uiConfig.ts | 1 + src/server-dev.ts | 1 + 4 files changed, 99 insertions(+), 2 deletions(-) diff --git a/frontend/src/component/feature/FeatureView/FeatureOverview/FeatureOverviewMetaData/FeatureOverviewMetaData.tsx b/frontend/src/component/feature/FeatureView/FeatureOverview/FeatureOverviewMetaData/FeatureOverviewMetaData.tsx index fcc6a6b7cf..02b07e5265 100644 --- a/frontend/src/component/feature/FeatureView/FeatureOverview/FeatureOverviewMetaData/FeatureOverviewMetaData.tsx +++ b/frontend/src/component/feature/FeatureView/FeatureOverview/FeatureOverviewMetaData/FeatureOverviewMetaData.tsx @@ -1,5 +1,12 @@ 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 { FeatureArchiveDialog } from 'component/common/FeatureArchiveDialog/FeatureArchiveDialog'; import { FeatureArchiveNotAllowedDialog } from 'component/common/FeatureArchiveDialog/FeatureArchiveNotAllowedDialog'; @@ -15,7 +22,14 @@ import { capitalizeFirst } from 'utils/capitalizeFirst'; import { Collaborators } from './Collaborators'; import { EnvironmentVisibilityMenu } from './EnvironmentVisibilityMenu/EnvironmentVisibilityMenu'; 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 }) => ({ padding: theme.spacing(3), @@ -29,6 +43,7 @@ const StyledMetaDataContainer = styled('div')(({ theme }) => ({ [theme.breakpoints.down('md')]: { width: '100%', }, + marginBottom: theme.spacing(2), })); const StyledTitle = styled('h2')(({ theme }) => ({ @@ -65,6 +80,10 @@ export const StyledMetaDataItemValue = styled('div')(({ theme }) => ({ gap: theme.spacing(1), })); +export const StyledListItemIcon = styled(ListItemIcon)(({ theme }) => ({ + minWidth: theme.spacing(5), +})); + type FeatureOverviewMetaDataProps = { hiddenEnvironments?: string[]; onEnvironmentVisibilityChange?: (environment: string) => void; @@ -72,6 +91,74 @@ type FeatureOverviewMetaDataProps = { onChange: () => void; }; +const FeatureLinks: FC<{ links: FeatureLink[] }> = ({ links }) => { + return links.length === 0 ? ( + + + You can now add links{' '} + + New + + + + Gather relevant links for external resources such as issue + trackers, code repositories or analytics tooling + +
+ +
+
+ ) : ( + + Resources + + {links.map((link) => ( + + + + + + + ))} + + +
+ +
+
+ ); +}; + const FeatureOverviewMetaData: FC = ({ hiddenEnvironments, onEnvironmentVisibilityChange, @@ -89,8 +176,13 @@ const FeatureOverviewMetaData: FC = ({ const showDependentFeatures = useShowDependentFeatures(project); + const featureLinksEnabled = useUiFlag('featureLinks'); + return ( <> + {featureLinksEnabled ? ( + + ) : null}
Flag details diff --git a/frontend/src/interfaces/featureToggle.ts b/frontend/src/interfaces/featureToggle.ts index 8136f16f63..78e2866d44 100644 --- a/frontend/src/interfaces/featureToggle.ts +++ b/frontend/src/interfaces/featureToggle.ts @@ -49,6 +49,8 @@ export type CollaboratorData = { users: Collaborator[]; }; +export type FeatureLink = { url: string; title: string | null; id: string }; + /** * @deprecated use FeatureSchema from openapi */ @@ -76,6 +78,7 @@ export interface IFeatureToggle { imageUrl: string; }; collaborators?: CollaboratorData; + links?: FeatureLink[]; } export interface IDependency { diff --git a/frontend/src/interfaces/uiConfig.ts b/frontend/src/interfaces/uiConfig.ts index aa230fc7a1..822fddd1e8 100644 --- a/frontend/src/interfaces/uiConfig.ts +++ b/frontend/src/interfaces/uiConfig.ts @@ -95,6 +95,7 @@ export type UiFlags = { flagsReleaseManagementUI?: boolean; cleanupReminder?: boolean; registerFrontendClient?: boolean; + featureLinks?: boolean; }; export interface IVersionInfo { diff --git a/src/server-dev.ts b/src/server-dev.ts index 50d0eb679e..7bb501a5d9 100644 --- a/src/server-dev.ts +++ b/src/server-dev.ts @@ -61,6 +61,7 @@ process.nextTick(async () => { cleanupReminder: true, strictSchemaValidation: true, registerFrontendClient: true, + featureLinks: true, }, }, authentication: {