mirror of
				https://github.com/Unleash/unleash.git
				synced 2025-10-27 11:02:16 +01:00 
			
		
		
		
	feat: Preview dependency (#7284)
This commit is contained in:
		
							parent
							
								
									c129541df6
								
							
						
					
					
						commit
						e621c7a2a5
					
				| @ -0,0 +1,62 @@ | |||||||
|  | import { screen } from '@testing-library/react'; | ||||||
|  | import { render } from 'utils/testRenderer'; | ||||||
|  | import { PrimaryFeatureInfo } from './FeatureOverviewCell'; | ||||||
|  | import userEvent from '@testing-library/user-event'; | ||||||
|  | import { testServerRoute, testServerSetup } from 'utils/testServer'; | ||||||
|  | 
 | ||||||
|  | const server = testServerSetup(); | ||||||
|  | 
 | ||||||
|  | test('Preview parent feature', async () => { | ||||||
|  |     testServerRoute(server, '/api/admin/projects/default/features/featureA', { | ||||||
|  |         children: [], | ||||||
|  |         dependencies: [{ feature: 'featureB' }], | ||||||
|  |     }); | ||||||
|  | 
 | ||||||
|  |     render( | ||||||
|  |         <PrimaryFeatureInfo | ||||||
|  |             feature='featureA' | ||||||
|  |             project='default' | ||||||
|  |             type='release' | ||||||
|  |             searchQuery='' | ||||||
|  |             dependencyType='child' | ||||||
|  |             onTypeClick={() => {}} | ||||||
|  |             delay={0} | ||||||
|  |         />, | ||||||
|  |     ); | ||||||
|  | 
 | ||||||
|  |     const childBadge = screen.getByText('child'); | ||||||
|  |     userEvent.hover(childBadge); | ||||||
|  | 
 | ||||||
|  |     await screen.findByText('Loading...'); | ||||||
|  | 
 | ||||||
|  |     await screen.findByText('Parent'); | ||||||
|  |     await screen.findByText('featureB'); | ||||||
|  | }); | ||||||
|  | 
 | ||||||
|  | test('Preview child features', async () => { | ||||||
|  |     testServerRoute(server, '/api/admin/projects/default/features/featureA', { | ||||||
|  |         children: ['featureB', 'featureC'], | ||||||
|  |         dependencies: [], | ||||||
|  |     }); | ||||||
|  | 
 | ||||||
|  |     render( | ||||||
|  |         <PrimaryFeatureInfo | ||||||
|  |             feature='featureA' | ||||||
|  |             project='default' | ||||||
|  |             type='release' | ||||||
|  |             searchQuery='' | ||||||
|  |             dependencyType='parent' | ||||||
|  |             onTypeClick={() => {}} | ||||||
|  |             delay={0} | ||||||
|  |         />, | ||||||
|  |     ); | ||||||
|  | 
 | ||||||
|  |     const parentBadge = screen.getByText('parent'); | ||||||
|  |     userEvent.hover(parentBadge); | ||||||
|  | 
 | ||||||
|  |     await screen.findByText('Loading...'); | ||||||
|  | 
 | ||||||
|  |     await screen.findByText('Children'); | ||||||
|  |     await screen.findByText('featureB'); | ||||||
|  |     await screen.findByText('featureC'); | ||||||
|  | }); | ||||||
| @ -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, styled } from '@mui/material'; | import { Box, IconButton, styled } 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'; | ||||||
| @ -9,7 +9,8 @@ import { StyledDescription, StyledTitle } from '../LinkCell/LinkCell.styles'; | |||||||
| import { Link } from 'react-router-dom'; | import { Link } from 'react-router-dom'; | ||||||
| import { Badge } from '../../../Badge/Badge'; | import { Badge } from '../../../Badge/Badge'; | ||||||
| import { HtmlTooltip } from '../../../HtmlTooltip/HtmlTooltip'; | import { HtmlTooltip } from '../../../HtmlTooltip/HtmlTooltip'; | ||||||
| import { ConditionallyRender } from '../../../ConditionallyRender/ConditionallyRender'; | import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; | ||||||
|  | import { useFeature } from 'hooks/api/getters/useFeature/useFeature'; | ||||||
| 
 | 
 | ||||||
| interface IFeatureNameCellProps { | interface IFeatureNameCellProps { | ||||||
|     row: { |     row: { | ||||||
| @ -191,14 +192,64 @@ const Tags: FC<{ | |||||||
|     ); |     ); | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| const PrimaryFeatureInfo: FC<{ | const StyledDependencyLink = styled(Link)({ | ||||||
|  |     display: 'block', | ||||||
|  | }); | ||||||
|  | 
 | ||||||
|  | const DependencyPreview: FC<{ feature: string; project: string }> = ({ | ||||||
|  |     feature, | ||||||
|  |     project, | ||||||
|  | }) => { | ||||||
|  |     const { feature: fetchedFeature } = useFeature(project, feature); | ||||||
|  |     const children = fetchedFeature.children; | ||||||
|  |     const parents = fetchedFeature.dependencies; | ||||||
|  | 
 | ||||||
|  |     if (children.length > 0) { | ||||||
|  |         return ( | ||||||
|  |             <> | ||||||
|  |                 <Box>Children</Box> | ||||||
|  | 
 | ||||||
|  |                 {children.map((child) => ( | ||||||
|  |                     <StyledDependencyLink | ||||||
|  |                         to={`/projects/${project}/features/${child}`} | ||||||
|  |                         key={child} | ||||||
|  |                     > | ||||||
|  |                         {child} | ||||||
|  |                     </StyledDependencyLink> | ||||||
|  |                 ))} | ||||||
|  |             </> | ||||||
|  |         ); | ||||||
|  |     } else if (parents[0]) { | ||||||
|  |         const parentFeature = parents[0].feature; | ||||||
|  |         return ( | ||||||
|  |             <> | ||||||
|  |                 <Box>Parent</Box> | ||||||
|  |                 <Link to={`/projects/${project}/features/${parentFeature}`}> | ||||||
|  |                     {parentFeature} | ||||||
|  |                 </Link> | ||||||
|  |             </> | ||||||
|  |         ); | ||||||
|  |     } | ||||||
|  |     return <>Loading...</>; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | export const PrimaryFeatureInfo: FC<{ | ||||||
|     project: string; |     project: string; | ||||||
|     feature: string; |     feature: string; | ||||||
|     searchQuery: string; |     searchQuery: string; | ||||||
|     type: string; |     type: string; | ||||||
|     dependencyType: string; |     dependencyType: string; | ||||||
|     onTypeClick: (type: string) => void; |     onTypeClick: (type: string) => void; | ||||||
| }> = ({ project, feature, type, searchQuery, dependencyType, onTypeClick }) => { |     delay?: number; | ||||||
|  | }> = ({ | ||||||
|  |     project, | ||||||
|  |     feature, | ||||||
|  |     type, | ||||||
|  |     searchQuery, | ||||||
|  |     dependencyType, | ||||||
|  |     onTypeClick, | ||||||
|  |     delay = 500, | ||||||
|  | }) => { | ||||||
|     const { featureTypes } = useFeatureTypes(); |     const { featureTypes } = useFeatureTypes(); | ||||||
|     const IconComponent = getFeatureTypeIcons(type); |     const IconComponent = getFeatureTypeIcons(type); | ||||||
|     const typeName = featureTypes.find( |     const typeName = featureTypes.find( | ||||||
| @ -208,14 +259,16 @@ const PrimaryFeatureInfo: FC<{ | |||||||
| 
 | 
 | ||||||
|     const TypeIcon = () => ( |     const TypeIcon = () => ( | ||||||
|         <HtmlTooltip arrow title={title} describeChild> |         <HtmlTooltip arrow title={title} describeChild> | ||||||
|             <IconComponent |             <IconButton | ||||||
|                 data-testid='feature-type-icon' |                 sx={{ p: 0 }} | ||||||
|                 sx={(theme) => ({ |                 aria-label={`add ${type} flag to filter`} | ||||||
|                     cursor: 'pointer', |  | ||||||
|                     fontSize: theme.spacing(2), |  | ||||||
|                 })} |  | ||||||
|                 onClick={() => onTypeClick(type)} |                 onClick={() => onTypeClick(type)} | ||||||
|  |             > | ||||||
|  |                 <IconComponent | ||||||
|  |                     sx={(theme) => ({ fontSize: theme.spacing(2) })} | ||||||
|  |                     data-testid='feature-type-icon' | ||||||
|                 /> |                 /> | ||||||
|  |             </IconButton> | ||||||
|         </HtmlTooltip> |         </HtmlTooltip> | ||||||
|     ); |     ); | ||||||
| 
 | 
 | ||||||
| @ -230,6 +283,16 @@ const PrimaryFeatureInfo: FC<{ | |||||||
|             <ConditionallyRender |             <ConditionallyRender | ||||||
|                 condition={Boolean(dependencyType)} |                 condition={Boolean(dependencyType)} | ||||||
|                 show={ |                 show={ | ||||||
|  |                     <HtmlTooltip | ||||||
|  |                         title={ | ||||||
|  |                             <DependencyPreview | ||||||
|  |                                 feature={feature} | ||||||
|  |                                 project={project} | ||||||
|  |                             /> | ||||||
|  |                         } | ||||||
|  |                         enterDelay={delay} | ||||||
|  |                         enterNextDelay={delay} | ||||||
|  |                     > | ||||||
|                         <DependencyBadge |                         <DependencyBadge | ||||||
|                             color={ |                             color={ | ||||||
|                                 dependencyType === 'parent' |                                 dependencyType === 'parent' | ||||||
| @ -239,6 +302,7 @@ const PrimaryFeatureInfo: FC<{ | |||||||
|                         > |                         > | ||||||
|                             {dependencyType} |                             {dependencyType} | ||||||
|                         </DependencyBadge> |                         </DependencyBadge> | ||||||
|  |                     </HtmlTooltip> | ||||||
|                 } |                 } | ||||||
|             /> |             /> | ||||||
|         </FeatureNameAndType> |         </FeatureNameAndType> | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user