mirror of
https://github.com/Unleash/unleash.git
synced 2025-08-04 13:48:56 +02:00
feat: wip
This commit is contained in:
parent
8360e3b6c5
commit
e107d73b2d
@ -13,6 +13,9 @@ import { ConditionallyRender } from 'component/common/ConditionallyRender/Condit
|
|||||||
import { useFeature } from 'hooks/api/getters/useFeature/useFeature';
|
import { useFeature } from 'hooks/api/getters/useFeature/useFeature';
|
||||||
import { useLocationSettings } from 'hooks/useLocationSettings';
|
import { useLocationSettings } from 'hooks/useLocationSettings';
|
||||||
import { getLocalizedDateString } from '../../../util';
|
import { getLocalizedDateString } from '../../../util';
|
||||||
|
import { Tag } from 'component/common/Tag/Tag';
|
||||||
|
import type { ITag } from 'interfaces/tags';
|
||||||
|
import { useUiFlag } from 'hooks/useUiFlag';
|
||||||
|
|
||||||
interface IFeatureNameCellProps {
|
interface IFeatureNameCellProps {
|
||||||
row: {
|
row: {
|
||||||
@ -36,7 +39,7 @@ const StyledFeatureLink = styled(Link)({
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const Tag = styled('button')(({ theme }) => ({
|
const CustomTagButton = styled('button')(({ theme }) => ({
|
||||||
marginRight: theme.spacing(0.5),
|
marginRight: theme.spacing(0.5),
|
||||||
border: `1px solid ${theme.palette.divider}`,
|
border: `1px solid ${theme.palette.divider}`,
|
||||||
borderRadius: theme.shape.borderRadius,
|
borderRadius: theme.shape.borderRadius,
|
||||||
@ -51,6 +54,22 @@ const Tag = styled('button')(({ theme }) => ({
|
|||||||
color: 'inherit',
|
color: 'inherit',
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
const StyledTag = styled('div')(({ theme }) => ({
|
||||||
|
display: 'flex',
|
||||||
|
alignItems: 'center',
|
||||||
|
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,
|
||||||
|
}));
|
||||||
|
|
||||||
const CappedDescription: FC<{ text: string; searchQuery: string }> = ({
|
const CappedDescription: FC<{ text: string; searchQuery: string }> = ({
|
||||||
text,
|
text,
|
||||||
searchQuery,
|
searchQuery,
|
||||||
@ -80,19 +99,6 @@ const CappedDescription: FC<{ text: string; searchQuery: string }> = ({
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const CappedTag: FC<{ tag: string; children: ReactElement }> = ({
|
|
||||||
tag,
|
|
||||||
children,
|
|
||||||
}) => {
|
|
||||||
return (
|
|
||||||
<ConditionallyRender
|
|
||||||
condition={tag.length > 30}
|
|
||||||
show={<HtmlTooltip title={tag}>{children}</HtmlTooltip>}
|
|
||||||
elseShow={children}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
const Container = styled(Box)(({ theme }) => ({
|
const Container = styled(Box)(({ theme }) => ({
|
||||||
display: 'flex',
|
display: 'flex',
|
||||||
flexDirection: 'column',
|
flexDirection: 'column',
|
||||||
@ -158,23 +164,26 @@ const ArchivedFeatureName: FC<{
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const RestTags: FC<{ tags: string[]; onClick: (tag: string) => void }> = ({
|
const RestTags: FC<{
|
||||||
tags,
|
tags: ITag[];
|
||||||
onClick,
|
onClick: (tag: string) => void;
|
||||||
}) => {
|
isTagTypeColorEnabled: boolean;
|
||||||
|
}> = ({ tags, onClick, isTagTypeColorEnabled }) => {
|
||||||
return (
|
return (
|
||||||
<HtmlTooltip
|
<HtmlTooltip
|
||||||
title={tags.map((tag) => (
|
title={tags.map((tag) => (
|
||||||
<Box
|
<Box
|
||||||
sx={{ cursor: 'pointer' }}
|
sx={{ cursor: 'pointer' }}
|
||||||
onClick={() => onClick(tag)}
|
onClick={() => onClick(`${tag.type}:${tag.value}`)}
|
||||||
key={tag}
|
key={`${tag.type}:${tag.value}`}
|
||||||
>
|
>
|
||||||
{tag}
|
{`${tag.type}:${tag.value}`}
|
||||||
</Box>
|
</Box>
|
||||||
))}
|
))}
|
||||||
>
|
>
|
||||||
<Tag sx={{ cursor: 'initial' }}>{tags.length} more...</Tag>
|
<CustomTagButton sx={{ cursor: 'initial' }}>
|
||||||
|
{tags.length} more...
|
||||||
|
</CustomTagButton>
|
||||||
</HtmlTooltip>
|
</HtmlTooltip>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
@ -183,30 +192,77 @@ const Tags: FC<{
|
|||||||
tags: FeatureSearchResponseSchema['tags'];
|
tags: FeatureSearchResponseSchema['tags'];
|
||||||
onClick: (tag: string) => void;
|
onClick: (tag: string) => void;
|
||||||
}> = ({ tags, onClick }) => {
|
}> = ({ tags, onClick }) => {
|
||||||
const [tag1, tag2, tag3, ...restTags] = (tags || []).map(
|
const isTagTypeColorEnabled = useUiFlag('tagTypeColor');
|
||||||
({ type, value }) => `${type}:${value}`,
|
|
||||||
);
|
if (!tags || tags.length === 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert TagSchema to ITag for the Tag component
|
||||||
|
const tagsAsITag: ITag[] = tags.map((tag) => ({
|
||||||
|
type: tag.type,
|
||||||
|
value: tag.value,
|
||||||
|
color: (tag as ITag).color, // Cast to ITag to get the color if available
|
||||||
|
}));
|
||||||
|
|
||||||
|
const [tag1, tag2, tag3, ...restTags] = tagsAsITag;
|
||||||
|
|
||||||
|
const handleTagClick = (tag: ITag) => {
|
||||||
|
onClick(`${tag.type}:${tag.value}`);
|
||||||
|
};
|
||||||
|
|
||||||
|
const renderCappedTag = (tag: ITag) => {
|
||||||
|
const tagFullText = `${tag.type}:${tag.value}`;
|
||||||
|
const needsTooltip = tagFullText.length > 30;
|
||||||
|
|
||||||
|
if (isTagTypeColorEnabled) {
|
||||||
|
const tagComponent = (
|
||||||
|
<Box
|
||||||
|
onClick={() => handleTagClick(tag)}
|
||||||
|
sx={{ cursor: 'pointer' }}
|
||||||
|
>
|
||||||
|
<Tag tag={tag} />
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
|
|
||||||
|
return needsTooltip ? (
|
||||||
|
<HtmlTooltip key={tagFullText} title={tagFullText}>
|
||||||
|
{tagComponent}
|
||||||
|
</HtmlTooltip>
|
||||||
|
) : (
|
||||||
|
<Box key={tagFullText}>{tagComponent}</Box>
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
// Fallback to simple tag rendering without color
|
||||||
|
return (
|
||||||
|
<HtmlTooltip
|
||||||
|
key={tagFullText}
|
||||||
|
title={needsTooltip ? tagFullText : ''}
|
||||||
|
>
|
||||||
|
<StyledTag onClick={() => handleTagClick(tag)}>
|
||||||
|
{tagFullText.length > 25
|
||||||
|
? `${tagFullText.substring(0, 25)}…`
|
||||||
|
: tagFullText}
|
||||||
|
</StyledTag>
|
||||||
|
</HtmlTooltip>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<TagsContainer>
|
<TagsContainer>
|
||||||
{tag1 && (
|
{tag1 && renderCappedTag(tag1)}
|
||||||
<CappedTag tag={tag1}>
|
{tag2 && renderCappedTag(tag2)}
|
||||||
<Tag onClick={() => onClick(tag1)}>{tag1}</Tag>
|
{tag3 && renderCappedTag(tag3)}
|
||||||
</CappedTag>
|
|
||||||
)}
|
|
||||||
{tag2 && (
|
|
||||||
<CappedTag tag={tag2}>
|
|
||||||
<Tag onClick={() => onClick(tag2)}>{tag2}</Tag>
|
|
||||||
</CappedTag>
|
|
||||||
)}
|
|
||||||
{tag3 && (
|
|
||||||
<CappedTag tag={tag3}>
|
|
||||||
<Tag onClick={() => onClick(tag3)}>{tag3}</Tag>
|
|
||||||
</CappedTag>
|
|
||||||
)}
|
|
||||||
<ConditionallyRender
|
<ConditionallyRender
|
||||||
condition={restTags.length > 0}
|
condition={restTags.length > 0}
|
||||||
show={<RestTags tags={restTags} onClick={onClick} />}
|
show={
|
||||||
|
<RestTags
|
||||||
|
tags={restTags}
|
||||||
|
onClick={onClick}
|
||||||
|
isTagTypeColorEnabled={isTagTypeColorEnabled}
|
||||||
|
/>
|
||||||
|
}
|
||||||
/>
|
/>
|
||||||
</TagsContainer>
|
</TagsContainer>
|
||||||
);
|
);
|
||||||
|
@ -8,6 +8,7 @@ const StyledChip = styled(Chip)<{ $color?: string }>(({ theme, $color }) => ({
|
|||||||
border: `1px solid ${theme.palette.divider}`,
|
border: `1px solid ${theme.palette.divider}`,
|
||||||
backgroundColor: theme.palette.common.white,
|
backgroundColor: theme.palette.common.white,
|
||||||
color: theme.palette.text.primary,
|
color: theme.palette.text.primary,
|
||||||
|
height: '26px',
|
||||||
'& .MuiChip-label': {
|
'& .MuiChip-label': {
|
||||||
display: 'flex',
|
display: 'flex',
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
|
@ -13,6 +13,7 @@ import { projectEnvironmentSchema } from './project-environment-schema';
|
|||||||
import { createStrategyVariantSchema } from './create-strategy-variant-schema';
|
import { createStrategyVariantSchema } from './create-strategy-variant-schema';
|
||||||
import { strategyVariantSchema } from './strategy-variant-schema';
|
import { strategyVariantSchema } from './strategy-variant-schema';
|
||||||
import { createFeatureNamingPatternSchema } from './create-feature-naming-pattern-schema';
|
import { createFeatureNamingPatternSchema } from './create-feature-naming-pattern-schema';
|
||||||
|
import { tagSchema } from './tag-schema';
|
||||||
|
|
||||||
export const deprecatedProjectOverviewSchema = {
|
export const deprecatedProjectOverviewSchema = {
|
||||||
$id: '#/components/schemas/deprecatedProjectOverviewSchema',
|
$id: '#/components/schemas/deprecatedProjectOverviewSchema',
|
||||||
@ -136,6 +137,7 @@ export const deprecatedProjectOverviewSchema = {
|
|||||||
createStrategyVariantSchema,
|
createStrategyVariantSchema,
|
||||||
constraintSchema,
|
constraintSchema,
|
||||||
featureSchema,
|
featureSchema,
|
||||||
|
tagSchema,
|
||||||
featureEnvironmentSchema,
|
featureEnvironmentSchema,
|
||||||
overrideSchema,
|
overrideSchema,
|
||||||
parametersSchema,
|
parametersSchema,
|
||||||
|
@ -13,6 +13,7 @@ import { projectEnvironmentSchema } from './project-environment-schema';
|
|||||||
import { createStrategyVariantSchema } from './create-strategy-variant-schema';
|
import { createStrategyVariantSchema } from './create-strategy-variant-schema';
|
||||||
import { strategyVariantSchema } from './strategy-variant-schema';
|
import { strategyVariantSchema } from './strategy-variant-schema';
|
||||||
import { createFeatureNamingPatternSchema } from './create-feature-naming-pattern-schema';
|
import { createFeatureNamingPatternSchema } from './create-feature-naming-pattern-schema';
|
||||||
|
import { tagSchema } from '../../services/tag-schema';
|
||||||
|
|
||||||
export const healthOverviewSchema = {
|
export const healthOverviewSchema = {
|
||||||
$id: '#/components/schemas/healthOverviewSchema',
|
$id: '#/components/schemas/healthOverviewSchema',
|
||||||
@ -125,6 +126,7 @@ export const healthOverviewSchema = {
|
|||||||
components: {
|
components: {
|
||||||
schemas: {
|
schemas: {
|
||||||
environmentSchema,
|
environmentSchema,
|
||||||
|
tagSchema,
|
||||||
projectEnvironmentSchema,
|
projectEnvironmentSchema,
|
||||||
createFeatureStrategySchema,
|
createFeatureStrategySchema,
|
||||||
createStrategyVariantSchema,
|
createStrategyVariantSchema,
|
||||||
|
@ -59,7 +59,7 @@ process.nextTick(async () => {
|
|||||||
teamsIntegrationChangeRequests: true,
|
teamsIntegrationChangeRequests: true,
|
||||||
simplifyDisableFeature: true,
|
simplifyDisableFeature: true,
|
||||||
adminNavUI: false,
|
adminNavUI: false,
|
||||||
tagTypeColor: true,
|
tagTypeColor: false,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
authentication: {
|
authentication: {
|
||||||
|
Loading…
Reference in New Issue
Block a user