11import { DatasetSchemaQuery } from '@/graphql/dataprotector/graphql' ;
22import { cn } from '@/lib/utils' ;
33import React from 'react' ;
4+ import {
5+ Tooltip ,
6+ TooltipContent ,
7+ TooltipProvider ,
8+ TooltipTrigger ,
9+ } from '@/components/ui/tooltip' ;
410import { pluralize } from '@/utils/pluralize' ;
511import { borderTypeColor } from '../../borderTypeColor' ;
612
7- interface TypeBadgeProps {
13+ export interface TypeBadgeProps {
814 schemaPaths ?: NonNullable <
915 NonNullable < DatasetSchemaQuery [ 'protectedData' ] > [ 'schema' ]
1016 > ;
@@ -13,15 +19,74 @@ interface TypeBadgeProps {
1319 direction ?: 'vertical' | 'horizontal' ;
1420 className ?: string ;
1521 overflowHidden ?: boolean ;
22+ enableTooltip ?: boolean ;
1623}
1724
25+ const getBorderColor = ( type : string ) => {
26+ return borderTypeColor . find ( ( color ) =>
27+ color . keywords . some ( ( keyword ) => type ?. toLowerCase ( ) . includes ( keyword ) )
28+ ) ?. color ;
29+ } ;
30+
31+ const renderBadge = (
32+ schema : { path : string ; type : string } ,
33+ overflowHidden : boolean
34+ ) => (
35+ < span
36+ key = { schema . path + schema . type }
37+ className = { cn (
38+ 'inline-flex w-fit rounded-full border px-4 py-2 text-xs' ,
39+ getBorderColor ( schema . type ) ,
40+ overflowHidden && 'max-w-36'
41+ ) }
42+ title = { overflowHidden ? `${ schema . path } : ${ schema . type } ` : undefined }
43+ >
44+ < span
45+ className = { cn (
46+ 'inline-block' ,
47+ overflowHidden && 'max-w-18 truncate overflow-hidden text-ellipsis'
48+ ) }
49+ >
50+ { schema . path }
51+ </ span >
52+ < span
53+ className = { cn (
54+ 'inline-block min-w-0 flex-1' ,
55+ overflowHidden && 'truncate overflow-hidden text-ellipsis'
56+ ) }
57+ >
58+ : { schema . type }
59+ </ span >
60+ </ span >
61+ ) ;
62+
63+ const renderTooltipContent = (
64+ schemaPaths : { path : string ; type : string } [ ]
65+ ) => (
66+ < div className = "flex flex-col gap-1" >
67+ { schemaPaths . map ( ( schema ) => (
68+ < div
69+ key = { schema . path + schema . type }
70+ className = { cn (
71+ 'rounded-full border px-3 py-1 text-xs whitespace-nowrap' ,
72+ getBorderColor ( schema . type )
73+ ) }
74+ >
75+ < span className = "font-semibold" > { schema . path } </ span >
76+ < span > : { schema . type } </ span >
77+ </ div >
78+ ) ) }
79+ </ div >
80+ ) ;
81+
1882const TypeBadge : React . FC < TypeBadgeProps > = ( {
1983 schemaPaths,
2084 isLoading,
2185 maxVisible = 2 ,
2286 direction = 'vertical' ,
2387 className,
2488 overflowHidden = true ,
89+ enableTooltip = false ,
2590} ) => {
2691 if ( isLoading && schemaPaths && schemaPaths . length === 0 ) {
2792 return (
@@ -36,7 +101,32 @@ const TypeBadge: React.FC<TypeBadgeProps> = ({
36101 const visibleItems = schemaPaths . slice ( 0 , maxVisible ) ;
37102 const hiddenCount = schemaPaths . length - visibleItems . length ;
38103
39- return (
104+ const badges = [
105+ ...visibleItems . map ( ( schema ) =>
106+ renderBadge (
107+ {
108+ path : schema . path ?? '' ,
109+ type : schema . type ?? '' ,
110+ } ,
111+ overflowHidden
112+ )
113+ ) ,
114+ hiddenCount > 0 ? (
115+ < span
116+ key = "more"
117+ className = "w-fit cursor-pointer text-xs text-gray-500 hover:bg-gray-100"
118+ >
119+ +{ pluralize ( hiddenCount , 'other' ) }
120+ </ span >
121+ ) : null ,
122+ ] ;
123+
124+ const safeSchemaPaths = schemaPaths . map ( ( schema ) => ( {
125+ path : schema . path ?? '' ,
126+ type : schema . type ?? '' ,
127+ } ) ) ;
128+
129+ const content = (
40130 < div
41131 className = { cn (
42132 `flex` ,
@@ -46,51 +136,22 @@ const TypeBadge: React.FC<TypeBadgeProps> = ({
46136 className
47137 ) }
48138 >
49- { visibleItems . map ( ( schema , index ) => {
50- const borderColor = borderTypeColor . find ( ( color ) =>
51- color . keywords . some ( ( keyword ) =>
52- schema . type ?. toLowerCase ( ) . includes ( keyword )
53- )
54- ) ?. color ;
55- return (
56- < span
57- key = { index }
58- className = { cn (
59- 'inline-flex w-fit rounded-full border px-4 py-2 text-xs' ,
60- borderColor ,
61- overflowHidden && 'max-w-36'
62- ) }
63- title = {
64- overflowHidden ? `${ schema . path } : ${ schema . type } ` : undefined
65- }
66- >
67- < span
68- className = { cn (
69- 'inline-block' ,
70- overflowHidden &&
71- 'max-w-18 truncate overflow-hidden text-ellipsis'
72- ) }
73- >
74- { schema . path }
75- </ span >
76- < span
77- className = { cn (
78- 'inline-block min-w-0 flex-1' ,
79- overflowHidden && 'truncate overflow-hidden text-ellipsis'
80- ) }
81- >
82- : { schema . type }
83- </ span >
84- </ span >
85- ) ;
86- } ) }
87- { hiddenCount > 0 && (
88- < span className = "w-fit text-xs text-gray-500 hover:bg-gray-100" >
89- +{ pluralize ( hiddenCount , 'other' ) }
90- </ span >
91- ) }
139+ { badges }
92140 </ div >
93141 ) ;
142+
143+ if ( ! enableTooltip ) return content ;
144+
145+ return (
146+ < TooltipProvider >
147+ < Tooltip >
148+ < TooltipTrigger asChild > { content } </ TooltipTrigger >
149+ < TooltipContent className = "max-w-xs p-4" >
150+ { renderTooltipContent ( safeSchemaPaths ) }
151+ </ TooltipContent >
152+ </ Tooltip >
153+ </ TooltipProvider >
154+ ) ;
94155} ;
95156
96157export default TypeBadge ;
0 commit comments