@@ -15,7 +15,7 @@ import { Feature, FeatureRuleClauseOperator, UserSegment } from '@types';
1515import { truncateBySide } from 'utils/converts' ;
1616import { isNotEmptyObject } from 'utils/data-type' ;
1717import { cn } from 'utils/style' ;
18- import { IconInfo , IconPlus , IconTrash } from '@icons' ;
18+ import { IconClose , IconInfo , IconPlus , IconTrash } from '@icons' ;
1919import { UserMessage } from 'pages/feature-flag-details/targeting/individual-rule' ;
2020import { RuleClauseType } from 'pages/feature-flag-details/targeting/types' ;
2121import { FlagVariationPolygon } from 'pages/feature-flags/collection-layout/elements' ;
@@ -26,6 +26,7 @@ import Dropdown from 'components/dropdown';
2626import Form from 'components/form' ;
2727import Icon from 'components/icon' ;
2828import Input from 'components/input' ;
29+ import { Popover } from 'components/popover' ;
2930import { Tooltip } from 'components/tooltip' ;
3031import DropdownMenuWithSearch from 'elements/dropdown-with-search' ;
3132import FeatureFlagStatus from 'elements/feature-flag-status' ;
@@ -494,51 +495,34 @@ const RuleClausesForm = ({
494495 } }
495496 />
496497 ) : isUserSegment ? (
497- < >
498- < Dropdown
499- options = { segmentOptions }
500- multiselect
501- value = { ( value as string [ ] ) || [ ] }
502- labelCustom = {
503- selectedSegments . length
504- ? truncateBySide (
505- selectedSegments
506- . map ( item => item . name )
507- . join ( ', ' ) ,
508- 50
509- )
510- : ''
511- }
512- onChange = { val => {
513- const current =
514- ( value as string [ ] ) || [ ] ;
515- const next = current . includes (
516- val as string
517- )
518- ? current . filter ( v => v !== val )
519- : [ ...current , val as string ] ;
520- field . onChange ( next ) ;
521- } }
522- onClear = { ( ) => field . onChange ( [ ] ) }
523- placeholder = { t ( 'common:select-value' ) }
524- disabled = { ! segmentOptions ?. length }
525- className = "w-full [&>div>p]:truncate [&>div]:max-w-[calc(100%-36px)]"
526- />
527- { selectedSegments . length > 0 && (
528- < div className = "flex flex-col w-full gap-y-1 mt-2" >
529- { selectedSegments . map ( item => (
530- < Link
531- key = { item . id }
532- target = "_blank"
533- to = { `/${ currentEnvironment . urlCode } ${ PAGE_PATH_USER_SEGMENTS } /${ item . id } ` }
534- className = "typo-para-small text-primary-500 hover:underline truncate w-fit max-w-full"
535- >
536- { `${ item . name } (${ getSegmentSummary ( item , t ) } )` }
537- </ Link >
538- ) ) }
539- </ div >
540- ) }
541- </ >
498+ < Dropdown
499+ options = { segmentOptions }
500+ multiselect
501+ value = { ( value as string [ ] ) || [ ] }
502+ labelCustom = {
503+ selectedSegments . length
504+ ? truncateBySide (
505+ selectedSegments
506+ . map ( item => item . name )
507+ . join ( ', ' ) ,
508+ 50
509+ )
510+ : ''
511+ }
512+ onChange = { val => {
513+ const current = ( value as string [ ] ) || [ ] ;
514+ const next = current . includes (
515+ val as string
516+ )
517+ ? current . filter ( v => v !== val )
518+ : [ ...current , val as string ] ;
519+ field . onChange ( next ) ;
520+ } }
521+ onClear = { ( ) => field . onChange ( [ ] ) }
522+ placeholder = { t ( 'common:select-value' ) }
523+ disabled = { ! segmentOptions ?. length }
524+ className = "w-full [&>div>p]:truncate [&>div]:max-w-[calc(100%-36px)]"
525+ />
542526 ) : isFlag ? (
543527 < Dropdown
544528 options = { variationOptions }
@@ -575,6 +559,63 @@ const RuleClausesForm = ({
575559 />
576560 ) }
577561 </ Form . Control >
562+ { isUserSegment && selectedSegments . length > 0 && (
563+ < div className = "mt-0.5" >
564+ < Popover
565+ align = "start"
566+ trigger = {
567+ < div >
568+ < span className = "typo-para-small font-medium text-primary-500" >
569+ { t (
570+ 'common:show-count-user-segments' ,
571+ {
572+ count : selectedSegments . length
573+ }
574+ ) }
575+ </ span >
576+ </ div >
577+ }
578+ triggerCls = "w-fit justify-start"
579+ className = "flex flex-col w-[300px] gap-y-0.5 p-0 overflow-hidden"
580+ >
581+ < div className = "flex flex-col gap-y-0.5 max-h-[220px] overflow-y-auto small-scroll p-2" >
582+ { selectedSegments . map ( item => (
583+ < div
584+ key = { item . id }
585+ className = "flex items-center w-full gap-x-1 rounded hover:bg-gray-50"
586+ >
587+ < Link
588+ target = "_blank"
589+ to = { `/${ currentEnvironment . urlCode } ${ PAGE_PATH_USER_SEGMENTS } /${ item . id } ` }
590+ className = "typo-para-small text-primary-500 hover:underline truncate flex-1 min-w-0 px-1 py-1"
591+ >
592+ { `${ item . name } (${ getSegmentSummary ( item , t ) } )` }
593+ </ Link >
594+ < button
595+ type = "button"
596+ aria-label = { t (
597+ 'common:remove-item-from-selection' ,
598+ { name : item . name }
599+ ) }
600+ onClick = { ( ) => {
601+ const current =
602+ ( value as string [ ] ) || [ ] ;
603+ field . onChange (
604+ current . filter (
605+ v => v !== item . id
606+ )
607+ ) ;
608+ } }
609+ className = "flex-center shrink-0 size-5 mr-1 rounded text-gray-500 hover:text-gray-700 hover:bg-gray-200"
610+ >
611+ < Icon icon = { IconClose } size = "xxs" />
612+ </ button >
613+ </ div >
614+ ) ) }
615+ </ div >
616+ </ Popover >
617+ </ div >
618+ ) }
578619 < Form . Message />
579620 </ Form . Item >
580621 ) ;
0 commit comments