Skip to content

Commit 605c5d7

Browse files
committed
feat: integrate tooltip functionality into TypeBadge component in datasets table
1 parent 6d23773 commit 605c5d7

File tree

2 files changed

+111
-46
lines changed

2 files changed

+111
-46
lines changed
Lines changed: 106 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,16 @@
11
import { DatasetSchemaQuery } from '@/graphql/dataprotector/graphql';
22
import { cn } from '@/lib/utils';
33
import React from 'react';
4+
import {
5+
Tooltip,
6+
TooltipContent,
7+
TooltipProvider,
8+
TooltipTrigger,
9+
} from '@/components/ui/tooltip';
410
import { pluralize } from '@/utils/pluralize';
511
import { 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+
1882
const 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

96157
export default TypeBadge;

src/modules/datasets/datasetsTable/columns.tsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,11 @@ export const columns: ColumnDef<Dataset>[] = [
5050
const datasetSchema = row.original.schema;
5151
const isSchemasLoading = row.original.isSchemasLoading;
5252
return (
53-
<TypeBadge isLoading={isSchemasLoading} schemaPaths={datasetSchema} />
53+
<TypeBadge
54+
isLoading={isSchemasLoading}
55+
schemaPaths={datasetSchema}
56+
enableTooltip={true}
57+
/>
5458
);
5559
},
5660
},

0 commit comments

Comments
 (0)