mirror of
				https://github.com/Unleash/unleash.git
				synced 2025-10-27 11:02:16 +01:00 
			
		
		
		
	Constraint values preview and filtering (#9603)
Restore constraint accordion to flag page.
This commit is contained in:
		
							parent
							
								
									c161291d09
								
							
						
					
					
						commit
						d8c7e31b18
					
				| @ -1,4 +1,4 @@ | |||||||
| import type { ComponentProps, FC } from 'react'; | import type { ComponentProps, FC, ReactNode } from 'react'; | ||||||
| import { StrategyEvaluationItem } from '../StrategyEvaluationItem/StrategyEvaluationItem'; | import { StrategyEvaluationItem } from '../StrategyEvaluationItem/StrategyEvaluationItem'; | ||||||
| import type { ConstraintSchema } from 'openapi'; | import type { ConstraintSchema } from 'openapi'; | ||||||
| import { formatOperatorDescription } from 'component/common/ConstraintAccordion/ConstraintOperator/formatOperatorDescription'; | import { formatOperatorDescription } from 'component/common/ConstraintAccordion/ConstraintOperator/formatOperatorDescription'; | ||||||
| @ -48,6 +48,13 @@ const CaseSensitive: FC = () => { | |||||||
|     ); |     ); | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  | const StyledConstraintContainer = styled('div')(({ theme }) => ({ | ||||||
|  |     display: 'grid', | ||||||
|  |     gridTemplateColumns: 'repeat(3, auto)', | ||||||
|  |     gap: theme.spacing(2), | ||||||
|  |     placeItems: 'center', | ||||||
|  | })); | ||||||
|  | 
 | ||||||
| const StyledOperatorGroup = styled('div')(({ theme }) => ({ | const StyledOperatorGroup = styled('div')(({ theme }) => ({ | ||||||
|     display: 'flex', |     display: 'flex', | ||||||
|     alignItems: 'center', |     alignItems: 'center', | ||||||
| @ -60,9 +67,15 @@ const StyledConstraintName = styled('div')(({ theme }) => ({ | |||||||
|     overflow: 'hidden', |     overflow: 'hidden', | ||||||
| })); | })); | ||||||
| 
 | 
 | ||||||
| export const ConstraintItemHeader: FC< | type ConstraintItemHeaderProps = ConstraintSchema & { | ||||||
|     ConstraintSchema & Pick<ComponentProps<typeof ValuesList>, 'onSetTruncated'> |     viewMore?: ReactNode; | ||||||
| > = ({ onSetTruncated, ...constraint }) => { | } & Pick<ComponentProps<typeof ValuesList>, 'onSetTruncated'>; | ||||||
|  | 
 | ||||||
|  | export const ConstraintItemHeader: FC<ConstraintItemHeaderProps> = ({ | ||||||
|  |     onSetTruncated, | ||||||
|  |     viewMore, | ||||||
|  |     ...constraint | ||||||
|  | }) => { | ||||||
|     const { caseInsensitive, contextName, inverted, operator, value, values } = |     const { caseInsensitive, contextName, inverted, operator, value, values } = | ||||||
|         constraint; |         constraint; | ||||||
|     const { locationSettings } = useLocationSettings(); |     const { locationSettings } = useLocationSettings(); | ||||||
| @ -77,22 +90,29 @@ export const ConstraintItemHeader: FC< | |||||||
| 
 | 
 | ||||||
|     return ( |     return ( | ||||||
|         <StrategyEvaluationItem type='Constraint'> |         <StrategyEvaluationItem type='Constraint'> | ||||||
|             <StyledConstraintName> |             <StyledConstraintContainer> | ||||||
|                 <Truncator lines={2} title={contextName} arrow> |                 <StyledConstraintName> | ||||||
|                     {contextName} |                     <Truncator title={contextName} arrow> | ||||||
|                 </Truncator> |                         {contextName} | ||||||
|             </StyledConstraintName> |                     </Truncator> | ||||||
|             <StyledOperatorGroup> |                 </StyledConstraintName> | ||||||
|                 <Operator label={operator} inverted={inverted} /> |                 <StyledOperatorGroup> | ||||||
|                 {isCaseSensitive(operator, caseInsensitive) ? ( |                     <Operator label={operator} inverted={inverted} /> | ||||||
|                     <CaseSensitive /> |                     {isCaseSensitive(operator, caseInsensitive) ? ( | ||||||
|                 ) : null} |                         <CaseSensitive /> | ||||||
|             </StyledOperatorGroup> |                     ) : null} | ||||||
|             <ValuesList |                 </StyledOperatorGroup> | ||||||
|                 values={items} |                 <div> | ||||||
|                 onSetTruncated={onSetTruncated} |                     <div> | ||||||
|                 tooltips={tooltips} |                         <ValuesList | ||||||
|             /> |                             values={items} | ||||||
|  |                             onSetTruncated={onSetTruncated} | ||||||
|  |                             tooltips={tooltips} | ||||||
|  |                         /> | ||||||
|  |                         {viewMore} | ||||||
|  |                     </div> | ||||||
|  |                 </div> | ||||||
|  |             </StyledConstraintContainer> | ||||||
|         </StrategyEvaluationItem> |         </StrategyEvaluationItem> | ||||||
|     ); |     ); | ||||||
| }; | }; | ||||||
|  | |||||||
| @ -1,9 +1,10 @@ | |||||||
| import type { FC } from 'react'; | import type { FC } from 'react'; | ||||||
| import { styled, Tooltip } from '@mui/material'; | import { styled } from '@mui/material'; | ||||||
| import { | import { | ||||||
|     Truncator, |     Truncator, | ||||||
|     type TruncatorProps, |     type TruncatorProps, | ||||||
| } from 'component/common/Truncator/Truncator'; | } from 'component/common/Truncator/Truncator'; | ||||||
|  | import { TooltipResolver } from 'component/common/TooltipResolver/TooltipResolver'; | ||||||
| 
 | 
 | ||||||
| export type ValuesListProps = { | export type ValuesListProps = { | ||||||
|     values?: string[]; |     values?: string[]; | ||||||
| @ -14,7 +15,12 @@ const StyledValuesContainer = styled('div')({ | |||||||
|     flex: '1 1 0', |     flex: '1 1 0', | ||||||
| }); | }); | ||||||
| 
 | 
 | ||||||
| const StyledValueItem = styled('span')(({ theme }) => ({ | const StyledTruncator = styled(Truncator)({ | ||||||
|  |     padding: 0, | ||||||
|  |     margin: 0, | ||||||
|  | }); | ||||||
|  | 
 | ||||||
|  | const StyledValueItem = styled('li')(({ theme }) => ({ | ||||||
|     padding: theme.spacing(0.25), |     padding: theme.spacing(0.25), | ||||||
|     display: 'inline-block', |     display: 'inline-block', | ||||||
|     span: { |     span: { | ||||||
| @ -45,22 +51,30 @@ export const ValuesList: FC<ValuesListProps> = ({ | |||||||
|                     lines={2} |                     lines={2} | ||||||
|                     onSetTruncated={() => onSetTruncated?.(false)} |                     onSetTruncated={() => onSetTruncated?.(false)} | ||||||
|                 > |                 > | ||||||
|                     <Tooltip title={tooltips?.[values[0]] || ''}> |                     <TooltipResolver title={tooltips?.[values[0]] || ''}> | ||||||
|                         <span>{values[0]}</span> |                         <span>{values[0]}</span> | ||||||
|                     </Tooltip> |                     </TooltipResolver> | ||||||
|                 </Truncator> |                 </Truncator> | ||||||
|             </StyledSingleValue> |             </StyledSingleValue> | ||||||
|         ) : null} |         ) : null} | ||||||
|         {values && values?.length > 1 ? ( |         {values && values?.length > 1 ? ( | ||||||
|             <Truncator title='' lines={2} onSetTruncated={onSetTruncated}> |             <StyledTruncator | ||||||
|  |                 title='' | ||||||
|  |                 lines={2} | ||||||
|  |                 onSetTruncated={onSetTruncated} | ||||||
|  |                 component='ul' | ||||||
|  |             > | ||||||
|                 {values.map((value) => ( |                 {values.map((value) => ( | ||||||
|                     <Tooltip title={tooltips?.[value] || ''} key={value}> |                     <TooltipResolver | ||||||
|  |                         title={tooltips?.[value] || ''} | ||||||
|  |                         key={value} | ||||||
|  |                     > | ||||||
|                         <StyledValueItem> |                         <StyledValueItem> | ||||||
|                             <span>{value}</span> |                             <span>{value}</span> | ||||||
|                         </StyledValueItem> |                         </StyledValueItem> | ||||||
|                     </Tooltip> |                     </TooltipResolver> | ||||||
|                 ))} |                 ))} | ||||||
|             </Truncator> |             </StyledTruncator> | ||||||
|         ) : null} |         ) : null} | ||||||
|     </StyledValuesContainer> |     </StyledValuesContainer> | ||||||
| ); | ); | ||||||
|  | |||||||
| @ -30,7 +30,6 @@ interface IConstraintAccordionViewProps { | |||||||
| const StyledAccordion = styled(Accordion)(({ theme }) => ({ | const StyledAccordion = styled(Accordion)(({ theme }) => ({ | ||||||
|     border: `1px solid ${theme.palette.divider}`, |     border: `1px solid ${theme.palette.divider}`, | ||||||
|     borderRadius: theme.shape.borderRadiusMedium, |     borderRadius: theme.shape.borderRadiusMedium, | ||||||
|     backgroundColor: 'transparent', |  | ||||||
|     boxShadow: 'none', |     boxShadow: 'none', | ||||||
|     margin: 0, |     margin: 0, | ||||||
|     '&:before': { |     '&:before': { | ||||||
|  | |||||||
| @ -10,7 +10,7 @@ interface IConstraintAccordionViewBodyProps { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| const StyledValueContainer = styled('div')(({ theme }) => ({ | const StyledValueContainer = styled('div')(({ theme }) => ({ | ||||||
|     padding: theme.spacing(2, 0), |     padding: theme.spacing(1, 0), | ||||||
|     maxHeight: '400px', |     maxHeight: '400px', | ||||||
|     overflowY: 'auto', |     overflowY: 'auto', | ||||||
| })); | })); | ||||||
|  | |||||||
| @ -55,7 +55,6 @@ export const ConstraintAccordionViewHeader = ({ | |||||||
|             {flagOverviewRedesign ? ( |             {flagOverviewRedesign ? ( | ||||||
|                 <ConstraintAccordionViewHeaderInfo |                 <ConstraintAccordionViewHeaderInfo | ||||||
|                     constraint={constraint} |                     constraint={constraint} | ||||||
|                     singleValue={singleValue} |  | ||||||
|                     allowExpand={allowExpand} |                     allowExpand={allowExpand} | ||||||
|                     expanded={expanded} |                     expanded={expanded} | ||||||
|                     disabled={disabled} |                     disabled={disabled} | ||||||
|  | |||||||
| @ -1,9 +1,7 @@ | |||||||
| import { IconButton, styled } from '@mui/material'; | import { styled } from '@mui/material'; | ||||||
| import type { IConstraint } from 'interfaces/strategy'; | import type { IConstraint } from 'interfaces/strategy'; | ||||||
| import { ConstraintItemHeader } from 'component/common/ConstraintsList/ConstraintItemHeader/ConstraintItemHeader'; | import { ConstraintItemHeader } from 'component/common/ConstraintsList/ConstraintItemHeader/ConstraintItemHeader'; | ||||||
| import { useState } from 'react'; | import { useState } from 'react'; | ||||||
| import VisibilityIcon from '@mui/icons-material/Visibility'; |  | ||||||
| import VisibilityOffIcon from '@mui/icons-material/VisibilityOff'; |  | ||||||
| 
 | 
 | ||||||
| const StyledHeaderWrapper = styled('div')(({ theme }) => ({ | const StyledHeaderWrapper = styled('div')(({ theme }) => ({ | ||||||
|     display: 'flex', |     display: 'flex', | ||||||
| @ -24,9 +22,14 @@ const StyledHeaderMetaInfo = styled('div')(({ theme }) => ({ | |||||||
|     }, |     }, | ||||||
| })); | })); | ||||||
| 
 | 
 | ||||||
|  | const StyledExpandItem = styled('div')(({ theme }) => ({ | ||||||
|  |     color: theme.palette.text.secondary, | ||||||
|  |     margin: theme.spacing(0.25, 0, 0, 0.75), | ||||||
|  |     fontSize: theme.fontSizes.smallerBody, | ||||||
|  | })); | ||||||
|  | 
 | ||||||
| interface ConstraintAccordionViewHeaderMetaInfoProps { | interface ConstraintAccordionViewHeaderMetaInfoProps { | ||||||
|     constraint: IConstraint; |     constraint: IConstraint; | ||||||
|     singleValue: boolean; |  | ||||||
|     expanded: boolean; |     expanded: boolean; | ||||||
|     allowExpand: (shouldExpand: boolean) => void; |     allowExpand: (shouldExpand: boolean) => void; | ||||||
|     disabled?: boolean; |     disabled?: boolean; | ||||||
| @ -49,12 +52,16 @@ export const ConstraintAccordionViewHeaderInfo = ({ | |||||||
|                         setExpandable(state); |                         setExpandable(state); | ||||||
|                         allowExpand(state); |                         allowExpand(state); | ||||||
|                     }} |                     }} | ||||||
|  |                     viewMore={ | ||||||
|  |                         expandable ? ( | ||||||
|  |                             <StyledExpandItem> | ||||||
|  |                                 {expanded | ||||||
|  |                                     ? 'View less' | ||||||
|  |                                     : `View all (${constraint.values?.length})`} | ||||||
|  |                             </StyledExpandItem> | ||||||
|  |                         ) : null | ||||||
|  |                     } | ||||||
|                 /> |                 /> | ||||||
|                 {expandable ? ( |  | ||||||
|                     <IconButton type='button'> |  | ||||||
|                         {expanded ? <VisibilityOffIcon /> : <VisibilityIcon />} |  | ||||||
|                     </IconButton> |  | ||||||
|                 ) : null} |  | ||||||
|             </StyledHeaderMetaInfo> |             </StyledHeaderMetaInfo> | ||||||
|         </StyledHeaderWrapper> |         </StyledHeaderWrapper> | ||||||
|     ); |     ); | ||||||
|  | |||||||
| @ -20,10 +20,10 @@ export const ConstraintValueSearch = ({ | |||||||
|                     value={filter} |                     value={filter} | ||||||
|                     onChange={(e) => setFilter(e.target.value)} |                     onChange={(e) => setFilter(e.target.value)} | ||||||
|                     placeholder='Filter values' |                     placeholder='Filter values' | ||||||
|                     style={{ |                     sx={(theme) => ({ | ||||||
|                         width: '100%', |                         width: '100%', | ||||||
|                         margin: '1rem 0', |                         margin: theme.spacing(1, 0, 2), | ||||||
|                     }} |                     })} | ||||||
|                     variant='outlined' |                     variant='outlined' | ||||||
|                     size='small' |                     size='small' | ||||||
|                     InputProps={{ |                     InputProps={{ | ||||||
|  | |||||||
| @ -3,7 +3,7 @@ import type { FeatureStrategySchema } from 'openapi'; | |||||||
| import type { IFeatureStrategyPayload } from 'interfaces/strategy'; | import type { IFeatureStrategyPayload } from 'interfaces/strategy'; | ||||||
| import { useUiFlag } from 'hooks/useUiFlag'; | import { useUiFlag } from 'hooks/useUiFlag'; | ||||||
| import { StrategyExecution as LegacyStrategyExecution } from './LegacyStrategyExecution'; | import { StrategyExecution as LegacyStrategyExecution } from './LegacyStrategyExecution'; | ||||||
| import { ConstraintItemHeader } from 'component/common/ConstraintsList/ConstraintItemHeader/ConstraintItemHeader'; | import { ConstraintAccordionView } from 'component/common/NewConstraintAccordion/ConstraintAccordionView/ConstraintAccordionView'; | ||||||
| import { useStrategies } from 'hooks/api/getters/useStrategies/useStrategies'; | import { useStrategies } from 'hooks/api/getters/useStrategies/useStrategies'; | ||||||
| import { objectId } from 'utils/objectId'; | import { objectId } from 'utils/objectId'; | ||||||
| import { useCustomStrategyParameters } from './hooks/useCustomStrategyParameters'; | import { useCustomStrategyParameters } from './hooks/useCustomStrategyParameters'; | ||||||
| @ -53,10 +53,10 @@ export const StrategyExecution: FC<StrategyExecutionProps> = ({ | |||||||
|                 <SegmentItem segment={segment} key={segment.id} /> |                 <SegmentItem segment={segment} key={segment.id} /> | ||||||
|             ))} |             ))} | ||||||
|             {constraints?.map((constraint, index) => ( |             {constraints?.map((constraint, index) => ( | ||||||
|                 <ConstraintListItem key={`${objectId(constraint)}-${index}`}> |                 <ConstraintAccordionView | ||||||
|                     {/* FIXME: use constraint accordion */} |                     key={`${objectId(constraint)}-${index}`} | ||||||
|                     <ConstraintItemHeader {...constraint} /> |                     constraint={constraint} | ||||||
|                 </ConstraintListItem> |                 /> | ||||||
|             ))} |             ))} | ||||||
|             {(isCustomStrategy ? customStrategyItems : strategyParameters).map( |             {(isCustomStrategy ? customStrategyItems : strategyParameters).map( | ||||||
|                 (item, index) => ( |                 (item, index) => ( | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user