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 type { ConstraintSchema } from 'openapi'; | ||||
| 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 }) => ({ | ||||
|     display: 'flex', | ||||
|     alignItems: 'center', | ||||
| @ -60,9 +67,15 @@ const StyledConstraintName = styled('div')(({ theme }) => ({ | ||||
|     overflow: 'hidden', | ||||
| })); | ||||
| 
 | ||||
| export const ConstraintItemHeader: FC< | ||||
|     ConstraintSchema & Pick<ComponentProps<typeof ValuesList>, 'onSetTruncated'> | ||||
| > = ({ onSetTruncated, ...constraint }) => { | ||||
| type ConstraintItemHeaderProps = ConstraintSchema & { | ||||
|     viewMore?: ReactNode; | ||||
| } & Pick<ComponentProps<typeof ValuesList>, 'onSetTruncated'>; | ||||
| 
 | ||||
| export const ConstraintItemHeader: FC<ConstraintItemHeaderProps> = ({ | ||||
|     onSetTruncated, | ||||
|     viewMore, | ||||
|     ...constraint | ||||
| }) => { | ||||
|     const { caseInsensitive, contextName, inverted, operator, value, values } = | ||||
|         constraint; | ||||
|     const { locationSettings } = useLocationSettings(); | ||||
| @ -77,22 +90,29 @@ export const ConstraintItemHeader: FC< | ||||
| 
 | ||||
|     return ( | ||||
|         <StrategyEvaluationItem type='Constraint'> | ||||
|             <StyledConstraintName> | ||||
|                 <Truncator lines={2} title={contextName} arrow> | ||||
|                     {contextName} | ||||
|                 </Truncator> | ||||
|             </StyledConstraintName> | ||||
|             <StyledOperatorGroup> | ||||
|                 <Operator label={operator} inverted={inverted} /> | ||||
|                 {isCaseSensitive(operator, caseInsensitive) ? ( | ||||
|                     <CaseSensitive /> | ||||
|                 ) : null} | ||||
|             </StyledOperatorGroup> | ||||
|             <ValuesList | ||||
|                 values={items} | ||||
|                 onSetTruncated={onSetTruncated} | ||||
|                 tooltips={tooltips} | ||||
|             /> | ||||
|             <StyledConstraintContainer> | ||||
|                 <StyledConstraintName> | ||||
|                     <Truncator title={contextName} arrow> | ||||
|                         {contextName} | ||||
|                     </Truncator> | ||||
|                 </StyledConstraintName> | ||||
|                 <StyledOperatorGroup> | ||||
|                     <Operator label={operator} inverted={inverted} /> | ||||
|                     {isCaseSensitive(operator, caseInsensitive) ? ( | ||||
|                         <CaseSensitive /> | ||||
|                     ) : null} | ||||
|                 </StyledOperatorGroup> | ||||
|                 <div> | ||||
|                     <div> | ||||
|                         <ValuesList | ||||
|                             values={items} | ||||
|                             onSetTruncated={onSetTruncated} | ||||
|                             tooltips={tooltips} | ||||
|                         /> | ||||
|                         {viewMore} | ||||
|                     </div> | ||||
|                 </div> | ||||
|             </StyledConstraintContainer> | ||||
|         </StrategyEvaluationItem> | ||||
|     ); | ||||
| }; | ||||
|  | ||||
| @ -1,9 +1,10 @@ | ||||
| import type { FC } from 'react'; | ||||
| import { styled, Tooltip } from '@mui/material'; | ||||
| import { styled } from '@mui/material'; | ||||
| import { | ||||
|     Truncator, | ||||
|     type TruncatorProps, | ||||
| } from 'component/common/Truncator/Truncator'; | ||||
| import { TooltipResolver } from 'component/common/TooltipResolver/TooltipResolver'; | ||||
| 
 | ||||
| export type ValuesListProps = { | ||||
|     values?: string[]; | ||||
| @ -14,7 +15,12 @@ const StyledValuesContainer = styled('div')({ | ||||
|     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), | ||||
|     display: 'inline-block', | ||||
|     span: { | ||||
| @ -45,22 +51,30 @@ export const ValuesList: FC<ValuesListProps> = ({ | ||||
|                     lines={2} | ||||
|                     onSetTruncated={() => onSetTruncated?.(false)} | ||||
|                 > | ||||
|                     <Tooltip title={tooltips?.[values[0]] || ''}> | ||||
|                     <TooltipResolver title={tooltips?.[values[0]] || ''}> | ||||
|                         <span>{values[0]}</span> | ||||
|                     </Tooltip> | ||||
|                     </TooltipResolver> | ||||
|                 </Truncator> | ||||
|             </StyledSingleValue> | ||||
|         ) : null} | ||||
|         {values && values?.length > 1 ? ( | ||||
|             <Truncator title='' lines={2} onSetTruncated={onSetTruncated}> | ||||
|             <StyledTruncator | ||||
|                 title='' | ||||
|                 lines={2} | ||||
|                 onSetTruncated={onSetTruncated} | ||||
|                 component='ul' | ||||
|             > | ||||
|                 {values.map((value) => ( | ||||
|                     <Tooltip title={tooltips?.[value] || ''} key={value}> | ||||
|                     <TooltipResolver | ||||
|                         title={tooltips?.[value] || ''} | ||||
|                         key={value} | ||||
|                     > | ||||
|                         <StyledValueItem> | ||||
|                             <span>{value}</span> | ||||
|                         </StyledValueItem> | ||||
|                     </Tooltip> | ||||
|                     </TooltipResolver> | ||||
|                 ))} | ||||
|             </Truncator> | ||||
|             </StyledTruncator> | ||||
|         ) : null} | ||||
|     </StyledValuesContainer> | ||||
| ); | ||||
|  | ||||
| @ -30,7 +30,6 @@ interface IConstraintAccordionViewProps { | ||||
| const StyledAccordion = styled(Accordion)(({ theme }) => ({ | ||||
|     border: `1px solid ${theme.palette.divider}`, | ||||
|     borderRadius: theme.shape.borderRadiusMedium, | ||||
|     backgroundColor: 'transparent', | ||||
|     boxShadow: 'none', | ||||
|     margin: 0, | ||||
|     '&:before': { | ||||
|  | ||||
| @ -10,7 +10,7 @@ interface IConstraintAccordionViewBodyProps { | ||||
| } | ||||
| 
 | ||||
| const StyledValueContainer = styled('div')(({ theme }) => ({ | ||||
|     padding: theme.spacing(2, 0), | ||||
|     padding: theme.spacing(1, 0), | ||||
|     maxHeight: '400px', | ||||
|     overflowY: 'auto', | ||||
| })); | ||||
|  | ||||
| @ -55,7 +55,6 @@ export const ConstraintAccordionViewHeader = ({ | ||||
|             {flagOverviewRedesign ? ( | ||||
|                 <ConstraintAccordionViewHeaderInfo | ||||
|                     constraint={constraint} | ||||
|                     singleValue={singleValue} | ||||
|                     allowExpand={allowExpand} | ||||
|                     expanded={expanded} | ||||
|                     disabled={disabled} | ||||
|  | ||||
| @ -1,9 +1,7 @@ | ||||
| import { IconButton, styled } from '@mui/material'; | ||||
| import { styled } from '@mui/material'; | ||||
| import type { IConstraint } from 'interfaces/strategy'; | ||||
| import { ConstraintItemHeader } from 'component/common/ConstraintsList/ConstraintItemHeader/ConstraintItemHeader'; | ||||
| import { useState } from 'react'; | ||||
| import VisibilityIcon from '@mui/icons-material/Visibility'; | ||||
| import VisibilityOffIcon from '@mui/icons-material/VisibilityOff'; | ||||
| 
 | ||||
| const StyledHeaderWrapper = styled('div')(({ theme }) => ({ | ||||
|     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 { | ||||
|     constraint: IConstraint; | ||||
|     singleValue: boolean; | ||||
|     expanded: boolean; | ||||
|     allowExpand: (shouldExpand: boolean) => void; | ||||
|     disabled?: boolean; | ||||
| @ -49,12 +52,16 @@ export const ConstraintAccordionViewHeaderInfo = ({ | ||||
|                         setExpandable(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> | ||||
|         </StyledHeaderWrapper> | ||||
|     ); | ||||
|  | ||||
| @ -20,10 +20,10 @@ export const ConstraintValueSearch = ({ | ||||
|                     value={filter} | ||||
|                     onChange={(e) => setFilter(e.target.value)} | ||||
|                     placeholder='Filter values' | ||||
|                     style={{ | ||||
|                     sx={(theme) => ({ | ||||
|                         width: '100%', | ||||
|                         margin: '1rem 0', | ||||
|                     }} | ||||
|                         margin: theme.spacing(1, 0, 2), | ||||
|                     })} | ||||
|                     variant='outlined' | ||||
|                     size='small' | ||||
|                     InputProps={{ | ||||
|  | ||||
| @ -3,7 +3,7 @@ import type { FeatureStrategySchema } from 'openapi'; | ||||
| import type { IFeatureStrategyPayload } from 'interfaces/strategy'; | ||||
| import { useUiFlag } from 'hooks/useUiFlag'; | ||||
| 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 { objectId } from 'utils/objectId'; | ||||
| import { useCustomStrategyParameters } from './hooks/useCustomStrategyParameters'; | ||||
| @ -53,10 +53,10 @@ export const StrategyExecution: FC<StrategyExecutionProps> = ({ | ||||
|                 <SegmentItem segment={segment} key={segment.id} /> | ||||
|             ))} | ||||
|             {constraints?.map((constraint, index) => ( | ||||
|                 <ConstraintListItem key={`${objectId(constraint)}-${index}`}> | ||||
|                     {/* FIXME: use constraint accordion */} | ||||
|                     <ConstraintItemHeader {...constraint} /> | ||||
|                 </ConstraintListItem> | ||||
|                 <ConstraintAccordionView | ||||
|                     key={`${objectId(constraint)}-${index}`} | ||||
|                     constraint={constraint} | ||||
|                 /> | ||||
|             ))} | ||||
|             {(isCustomStrategy ? customStrategyItems : strategyParameters).map( | ||||
|                 (item, index) => ( | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user