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

feat: tags in project list

This commit is contained in:
FredrikOseberg 2025-03-19 22:57:32 +01:00
parent e107d73b2d
commit 613b77819f
No known key found for this signature in database
GPG Key ID: 282FD8A6D8F9BCF0
3 changed files with 39 additions and 48 deletions

View File

@ -1,6 +1,6 @@
import type { FC, ReactElement } from 'react'; import type { FC, ReactElement } from 'react';
import type { FeatureSearchResponseSchema } from '../../../../../openapi'; import type { FeatureSearchResponseSchema } from '../../../../../openapi';
import { Box, IconButton, styled } from '@mui/material'; import { Box, IconButton, styled, Chip } from '@mui/material';
import useFeatureTypes from 'hooks/api/getters/useFeatureTypes/useFeatureTypes'; import useFeatureTypes from 'hooks/api/getters/useFeatureTypes/useFeatureTypes';
import { getFeatureTypeIcons } from 'utils/getFeatureTypeIcons'; import { getFeatureTypeIcons } from 'utils/getFeatureTypeIcons';
import { useSearchHighlightContext } from '../../SearchHighlightContext/SearchHighlightContext'; import { useSearchHighlightContext } from '../../SearchHighlightContext/SearchHighlightContext';
@ -54,20 +54,13 @@ const CustomTagButton = styled('button')(({ theme }) => ({
color: 'inherit', color: 'inherit',
})); }));
const StyledTag = styled('div')(({ theme }) => ({ const StyledTag = styled(Chip)(({ theme }) => ({
display: 'flex', overflowWrap: 'anywhere',
alignItems: 'center', lineHeight: theme.typography.body1.lineHeight,
marginRight: theme.spacing(0.5),
border: `1px solid ${theme.palette.divider}`,
borderRadius: theme.shape.borderRadius,
fontSize: theme.fontSizes.smallerBody,
textOverflow: 'ellipsis',
overflow: 'hidden',
textWrap: 'nowrap',
maxWidth: '250px',
padding: theme.spacing(0.25, 0.5),
cursor: 'pointer',
backgroundColor: theme.palette.neutral.light, backgroundColor: theme.palette.neutral.light,
color: theme.palette.text.primary,
padding: theme.spacing(0.25),
height: theme.spacing(3.5),
})); }));
const CappedDescription: FC<{ text: string; searchQuery: string }> = ({ const CappedDescription: FC<{ text: string; searchQuery: string }> = ({
@ -164,11 +157,10 @@ const ArchivedFeatureName: FC<{
); );
}; };
const RestTags: FC<{ const RestTags: FC<{ tags: ITag[]; onClick: (tag: string) => void }> = ({
tags: ITag[]; tags,
onClick: (tag: string) => void; onClick,
isTagTypeColorEnabled: boolean; }) => {
}> = ({ tags, onClick, isTagTypeColorEnabled }) => {
return ( return (
<HtmlTooltip <HtmlTooltip
title={tags.map((tag) => ( title={tags.map((tag) => (
@ -211,9 +203,9 @@ const Tags: FC<{
onClick(`${tag.type}:${tag.value}`); onClick(`${tag.type}:${tag.value}`);
}; };
const renderCappedTag = (tag: ITag) => { const renderTag = (tag: ITag) => {
const tagFullText = `${tag.type}:${tag.value}`; const tagFullText = `${tag.type}:${tag.value}`;
const needsTooltip = tagFullText.length > 30; const isOverflowing = tagFullText.length > 30;
if (isTagTypeColorEnabled) { if (isTagTypeColorEnabled) {
const tagComponent = ( const tagComponent = (
@ -225,44 +217,43 @@ const Tags: FC<{
</Box> </Box>
); );
return needsTooltip ? (
<HtmlTooltip key={tagFullText} title={tagFullText}>
{tagComponent}
</HtmlTooltip>
) : (
<Box key={tagFullText}>{tagComponent}</Box>
);
} else {
// Fallback to simple tag rendering without color
return ( return (
<HtmlTooltip <HtmlTooltip
key={tagFullText} key={tagFullText}
title={needsTooltip ? tagFullText : ''} title={isOverflowing ? tagFullText : ''}
arrow
> >
<StyledTag onClick={() => handleTagClick(tag)}> <span>{tagComponent}</span>
{tagFullText.length > 25
? `${tagFullText.substring(0, 25)}`
: tagFullText}
</StyledTag>
</HtmlTooltip> </HtmlTooltip>
); );
} }
return (
<StyledTag
key={tagFullText}
label={
<HtmlTooltip title={isOverflowing ? tagFullText : ''} arrow>
<span>
{tagFullText.substring(0, 30)}
{isOverflowing ? '...' : ''}
</span>
</HtmlTooltip>
}
size='small'
onClick={() => handleTagClick(tag)}
sx={{ cursor: 'pointer' }}
/>
);
}; };
return ( return (
<TagsContainer> <TagsContainer>
{tag1 && renderCappedTag(tag1)} {tag1 && renderTag(tag1)}
{tag2 && renderCappedTag(tag2)} {tag2 && renderTag(tag2)}
{tag3 && renderCappedTag(tag3)} {tag3 && renderTag(tag3)}
<ConditionallyRender <ConditionallyRender
condition={restTags.length > 0} condition={restTags.length > 0}
show={ show={<RestTags tags={restTags} onClick={onClick} />}
<RestTags
tags={restTags}
onClick={onClick}
isTagTypeColorEnabled={isTagTypeColorEnabled}
/>
}
/> />
</TagsContainer> </TagsContainer>
); );

View File

@ -6,7 +6,7 @@ import type { ReactElement } from 'react';
const StyledChip = styled(Chip)<{ $color?: string }>(({ theme, $color }) => ({ const StyledChip = styled(Chip)<{ $color?: string }>(({ theme, $color }) => ({
borderRadius: theme.spacing(2), borderRadius: theme.spacing(2),
border: `1px solid ${theme.palette.divider}`, border: `1px solid ${theme.palette.divider}`,
backgroundColor: theme.palette.common.white, backgroundColor: theme.palette.background.paper,
color: theme.palette.text.primary, color: theme.palette.text.primary,
height: '26px', height: '26px',
'& .MuiChip-label': { '& .MuiChip-label': {

View File

@ -59,7 +59,7 @@ process.nextTick(async () => {
teamsIntegrationChangeRequests: true, teamsIntegrationChangeRequests: true,
simplifyDisableFeature: true, simplifyDisableFeature: true,
adminNavUI: false, adminNavUI: false,
tagTypeColor: false, tagTypeColor: true,
}, },
}, },
authentication: { authentication: {