Skip to content

Commit

Permalink
feat: parent and child info in feature overview header (#4901)
Browse files Browse the repository at this point in the history
  • Loading branch information
kwasniew committed Oct 2, 2023
1 parent 3a6e38a commit 40dfb92
Show file tree
Hide file tree
Showing 7 changed files with 127 additions and 25 deletions.
4 changes: 4 additions & 0 deletions frontend/src/assets/icons/link-child.svg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions frontend/src/assets/icons/link-parent.svg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 2 additions & 0 deletions frontend/src/component/changeRequest/ChangeRequest.test.tsx
Expand Up @@ -179,6 +179,8 @@ const feature = ({ name, enabled }: { name: string; enabled: boolean }) =>
lastSeenAt: null,
type: 'release',
archived: false,
dependencies: [],
children: [],
});

const otherRequests = (feature: string) => {
Expand Down
Expand Up @@ -170,6 +170,8 @@ const featureEnvironments = (
lastSeenAt: null,
type: 'release',
archived: false,
children: [],
dependencies: [],
});
};

Expand Down
@@ -0,0 +1,24 @@
import { StyledLink } from './StyledRow';
import { TooltipLink } from 'component/common/TooltipLink/TooltipLink';
import { FC } from 'react';

export const ChildrenTooltip: FC<{
childFeatures: string[];
project: string;
}> = ({ childFeatures, project }) => (
<TooltipLink
tooltip={
<>
{childFeatures.map(child => (
<StyledLink to={`/projects/${project}/features/${child}`}>
<div>{child}</div>
</StyledLink>
))}
</>
}
>
{childFeatures.length === 1
? '1 feature'
: `${childFeatures.length} features`}
</TooltipLink>
);
Expand Up @@ -9,6 +9,7 @@ import { FlexRow, StyledDetail, StyledLabel, StyledLink } from './StyledRow';
import { DependencyActions } from './DependencyActions';
import { useDependentFeaturesApi } from 'hooks/api/actions/useDependentFeaturesApi/useDependentFeaturesApi';
import { useFeature } from 'hooks/api/getters/useFeature/useFeature';
import { ChildrenTooltip } from './ChildrenTooltip';

export const DependencyRow: FC<{ feature: IFeatureToggle }> = ({ feature }) => {
const { removeDependencies } = useDependentFeaturesApi(feature.project);
Expand Down Expand Up @@ -71,23 +72,10 @@ export const DependencyRow: FC<{ feature: IFeatureToggle }> = ({ feature }) => {
<FlexRow>
<StyledDetail>
<StyledLabel>Children:</StyledLabel>
<TooltipLink
tooltip={
<>
{feature.children.map(child => (
<StyledLink
to={`/projects/${feature.project}/features/${child}`}
>
<div>{child}</div>
</StyledLink>
))}
</>
}
>
{feature.children.length === 1
? '1 feature'
: `${feature.children.length} features`}
</TooltipLink>
<ChildrenTooltip
childFeatures={feature.children}
project={feature.project}
/>
</StyledDetail>
</FlexRow>
}
Expand Down
95 changes: 87 additions & 8 deletions frontend/src/component/feature/FeatureView/FeatureView.tsx
@@ -1,5 +1,5 @@
import { useState } from 'react';
import { styled, Tab, Tabs, useMediaQuery } from '@mui/material';
import { styled, Tab, Tabs, useMediaQuery, Box, Card } from '@mui/material';
import { Archive, FileCopy, Label, WatchLater } from '@mui/icons-material';
import {
Link,
Expand Down Expand Up @@ -31,6 +31,11 @@ import { useRequiredPathParam } from 'hooks/useRequiredPathParam';
import { FeatureArchiveDialog } from 'component/common/FeatureArchiveDialog/FeatureArchiveDialog';
import { useFavoriteFeaturesApi } from 'hooks/api/actions/useFavoriteFeaturesApi/useFavoriteFeaturesApi';
import { FavoriteIconButton } from 'component/common/FavoriteIconButton/FavoriteIconButton';
import { ReactComponent as ChildLinkIcon } from 'assets/icons/link-child.svg';
import { ReactComponent as ParentLinkIcon } from 'assets/icons/link-parent.svg';
import { TooltipLink } from '../../common/TooltipLink/TooltipLink';
import { ChildrenTooltip } from './FeatureOverview/FeatureOverviewSidePanel/FeatureOverviewSidePanelDetails/ChildrenTooltip';
import { useUiFlag } from '../../../hooks/useUiFlag';

const StyledHeader = styled('div')(({ theme }) => ({
backgroundColor: theme.palette.background.paper,
Expand All @@ -53,6 +58,28 @@ const StyledToggleInfoContainer = styled('div')({
alignItems: 'center',
});

const StyledDependency = styled('div')(({ theme }) => ({
display: 'flex',
alignItems: 'center',
gap: theme.spacing(1),
marginTop: theme.spacing(1),
fontSize: theme.fontSizes.smallBody,
padding: theme.spacing(0.75, 1.5),
backgroundColor: theme.palette.background.elevation2,
borderRadius: `${theme.shape.borderRadiusMedium}px`,
width: 'max-content',
}));

const StyleChildLinkIcon = styled(ChildLinkIcon)(({ theme }) => ({
width: theme.fontSizes.smallBody,
height: theme.fontSizes.smallBody,
}));

const StyledParentLinkIcon = styled(ParentLinkIcon)(({ theme }) => ({
width: theme.fontSizes.smallBody,
height: theme.fontSizes.smallBody,
}));

const StyledFeatureViewHeader = styled('h1')(({ theme }) => ({
fontSize: theme.fontSizes.mainHeader,
fontWeight: 'normal',
Expand Down Expand Up @@ -86,12 +113,21 @@ const StyledTabButton = styled(Tab)(({ theme }) => ({
},
}));

export const StyledLink = styled(Link)(({ theme }) => ({
maxWidth: '100%',
textDecoration: 'none',
'&:hover, &:focus': {
textDecoration: 'underline',
},
}));

export const FeatureView = () => {
const projectId = useRequiredPathParam('projectId');
const featureId = useRequiredPathParam('featureId');
const { refetch: projectRefetch } = useProject(projectId);
const { favorite, unfavorite } = useFavoriteFeaturesApi();
const { refetchFeature } = useFeature(projectId, featureId);
const dependentFeatures = useUiFlag('dependentFeatures');

const [openTagDialog, setOpenTagDialog] = useState(false);
const [showDelDialog, setShowDelDialog] = useState(false);
Expand Down Expand Up @@ -157,13 +193,56 @@ export const FeatureView = () => {
onClick={onFavorite}
isFavorite={feature?.favorite}
/>
<StyledFeatureViewHeader data-loading>
{feature.name}{' '}
</StyledFeatureViewHeader>
<ConditionallyRender
condition={!smallScreen}
show={<FeatureStatusChip stale={feature?.stale} />}
/>
<div>
<StyledToggleInfoContainer>
<StyledFeatureViewHeader data-loading>
{feature.name}{' '}
</StyledFeatureViewHeader>
<ConditionallyRender
condition={!smallScreen}
show={
<FeatureStatusChip
stale={feature?.stale}
/>
}
/>
</StyledToggleInfoContainer>
<ConditionallyRender
condition={
dependentFeatures &&
feature.dependencies.length > 0
}
show={
<StyledDependency>
<StyleChildLinkIcon />{' '}
<b>Child feature</b>
<span>{' < '}</span>
<StyledLink
to={`/projects/${feature.project}/features/${feature?.dependencies[0]?.feature}`}
>
{feature?.dependencies[0]?.feature}
</StyledLink>
</StyledDependency>
}
/>
<ConditionallyRender
condition={
dependentFeatures &&
feature.children.length > 0
}
show={
<StyledDependency>
<StyledParentLinkIcon />{' '}
<b>Parent feature</b>
<span>{' > '}</span>
<ChildrenTooltip
childFeatures={feature.children}
project={feature.project}
/>
</StyledDependency>
}
/>
</div>
</StyledToggleInfoContainer>

<StyledToolbarContainer>
Expand Down

0 comments on commit 40dfb92

Please sign in to comment.