From f3827407b89adb67bc9cf9815c0e7225de0b48ec Mon Sep 17 00:00:00 2001 From: Leonardo <leomilho@gmail.com> Date: Thu, 11 Jul 2024 20:02:10 +0200 Subject: [PATCH] chore: fixes to merge --- .../VisualizationTooltip.module.scss | 6 + .../VisualizationTooltip.stories.tsx | 85 +++++++++++ .../VisualizationTooltip.tsx | 140 ++++++++++++++++++ .../components/VisualizationTooltip/index.tsx | 1 + 4 files changed, 232 insertions(+) create mode 100644 libs/shared/lib/components/VisualizationTooltip/VisualizationTooltip.module.scss create mode 100644 libs/shared/lib/components/VisualizationTooltip/VisualizationTooltip.stories.tsx create mode 100644 libs/shared/lib/components/VisualizationTooltip/VisualizationTooltip.tsx create mode 100644 libs/shared/lib/components/VisualizationTooltip/index.tsx diff --git a/libs/shared/lib/components/VisualizationTooltip/VisualizationTooltip.module.scss b/libs/shared/lib/components/VisualizationTooltip/VisualizationTooltip.module.scss new file mode 100644 index 000000000..87c1972b5 --- /dev/null +++ b/libs/shared/lib/components/VisualizationTooltip/VisualizationTooltip.module.scss @@ -0,0 +1,6 @@ +.diagonal-lines { + border: 1px solid lightgray; + background: + repeating-linear-gradient(-45deg, transparent, transparent 6px, #eaeaea 6px, #eaeaea 8px), + /* Gray diagonal lines */ linear-gradient(to bottom, transparent, transparent); /* Vertical gradient */ +} diff --git a/libs/shared/lib/components/VisualizationTooltip/VisualizationTooltip.stories.tsx b/libs/shared/lib/components/VisualizationTooltip/VisualizationTooltip.stories.tsx new file mode 100644 index 000000000..0a4f40459 --- /dev/null +++ b/libs/shared/lib/components/VisualizationTooltip/VisualizationTooltip.stories.tsx @@ -0,0 +1,85 @@ +import React, { useState } from 'react'; +import type { Meta, StoryObj } from '@storybook/react'; +import { VisualizationTooltip, CardToolTipVisProps } from '@graphpolaris/shared/lib/components/VisualizationTooltip'; + +const meta: Meta<typeof VisualizationTooltip> = { + component: VisualizationTooltip, + title: 'Components/VisualizationTooltip', +}; + +export default meta; +type Story = StoryObj<typeof VisualizationTooltip>; + +export const SchemaNode: Story = { + render: (args) => { + return ( + <div className="w-1/4 my-10 m-auto flex items-center justify-center"> + <VisualizationTooltip {...args} /> + </div> + ); + }, + args: { + type: 'schema', + typeOfSchema: 'node', + name: 'Person', + data: { + born: 'int', + name: 'string', + description: 'string', + }, + colorHeader: '#fb7b04', + numberOfElements: 1000, + }, +}; + +export const SchemaRelationship: Story = { + render: (args) => { + return ( + <div className="w-1/4 my-10 m-auto flex items-center justify-center"> + <VisualizationTooltip {...args} /> + </div> + ); + }, + args: { + type: 'schema', + typeOfSchema: 'relationship', + name: 'Directed', + data: { + born: 'int', + name: 'string', + description: 'string', + imdb: 'string', + imdbVotes: 'int', + }, + colorHeader: '#0676C1', + connectedTo: 'Person', + numberOfElements: 231230, + connectedFrom: 'Movie', + }, +}; + +export const PopUpVis: Story = { + render: (args) => { + return ( + <div className="w-1/4 my-10 m-auto flex items-center justify-center"> + <VisualizationTooltip {...args} /> + </div> + ); + }, + args: { + name: 'Person', + type: 'popupvis', + data: { + bio: 'From wikipedia was born in usa from a firefighter father', + name: 'Charlotte Henry', + born: {}, + imdbRank: 21213, + imdbVotes: 1213, + poster: 'https://image.tmdb.org/t/p/w440_and_h660_face/kTKiREs37qd8GUlNI4Koiupwy6W.jpg', + tmdbId: '94105', + country: undefined, + labels: ['Actor', 'Person', 'Human'], + }, + colorHeader: '#B69AEf', + }, +}; diff --git a/libs/shared/lib/components/VisualizationTooltip/VisualizationTooltip.tsx b/libs/shared/lib/components/VisualizationTooltip/VisualizationTooltip.tsx new file mode 100644 index 000000000..21a08ab4a --- /dev/null +++ b/libs/shared/lib/components/VisualizationTooltip/VisualizationTooltip.tsx @@ -0,0 +1,140 @@ +import React from 'react'; +import { Icon } from '@graphpolaris/shared/lib/components/icon'; +import { Numbers, Close } from '@mui/icons-material'; +import styles from './VisualizationTooltip.module.scss'; +import { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider } from '@graphpolaris/shared/lib/components/tooltip'; +import { + CarbonStringInteger, + CarbonStringText, + CarbonCalendar, + CarbonBoolean, + CarbonUndefined, +} from '@graphpolaris/shared/lib/assets/carbonIcons/carbonIcons'; + +export type CardToolTipVisProps = { + type: string; + name: string; + data: Record<string, any>; + typeOfSchema?: string; + colorHeader: string; + connectedTo?: string; + connectedFrom?: string; + maxVisibleItems?: number; + numberOfElements?: number; +}; + +const formatNumber = (number: number) => { + return number.toLocaleString('de-DE'); // Format number with dots as thousand separators +}; + +export const VisualizationTooltip: React.FC<CardToolTipVisProps> = ({ + type, + name, + data, + colorHeader, + maxVisibleItems = 5, + connectedFrom, + connectedTo, + typeOfSchema, + numberOfElements, +}) => { + const itemsToShow = Object.entries(data).slice(0, maxVisibleItems); + + return ( + <div className="border-1 border-sec-200 bg-white w-[12rem] -mx-2 -my-1"> + <div className="flex m-0 justify-start items-stretch border-b border-sec-200 relative"> + <div className="left-0 top-0 h-auto w-1.5" style={{ backgroundColor: colorHeader }}></div> + <div className="px-2.5 py-1 truncate flex"> + <Tooltip> + <TooltipTrigger className={'flex max-w-full'}> + <span className="text-base font-semibold truncate">{name}</span> + </TooltipTrigger> + <TooltipContent side={'top'}> + <span>{name}</span> + </TooltipContent> + </Tooltip> + </div> + {/* + <div className="flex-shrink-0 ml-2"> + <Button variantType="secondary" variant="ghost" size="xs" rounded={true} iconComponent={<Close />} onClick={() => {}} /> + </div> + */} + </div> + + {type === 'schema' && numberOfElements && ( + <div className="px-4 py-1 border-b border-sec-200"> + <div className="flex flex-row gap-1 items-center justify-between"> + <Icon component={<Numbers />} size={24} /> <span className="ml-auto text-right">{formatNumber(numberOfElements)}</span> + </div> + </div> + )} + + {type === 'schema' && typeOfSchema === 'relationship' && ( + <div className="px-4 py-1 border-b border-sec-200"> + <div className="flex flex-row gap-3 items-center justify-between"> + <span className="font-semibold">From</span> + <span className="ml-auto text-right">{connectedFrom}</span> + </div> + + <div className="flex flex-row gap-1 items-center justify-between"> + <span className="font-semibold">To</span> + <span className="ml-auto text-right">{connectedTo}</span> + </div> + </div> + )} + + <TooltipProvider delayDuration={300}> + <div className={`px-3 py-1.5 ${data.length > maxVisibleItems ? 'max-h-20 overflow-y-auto' : ''}`}> + {data && Object.keys(data).length === 0 ? ( + <div className="flex justify-center items-center h-full"> + <span>No attributes</span> + </div> + ) : ( + Object.entries(data).map(([k, v]) => ( + <Tooltip key={k}> + <div className="flex flex-row gap-1 items-center min-h-6"> + <span className={`font-semibold truncate ${type === 'schema' ? 'w-[90%]' : 'min-w-[40%]'}`}>{k}</span> + <TooltipTrigger asChild> + <span className="ml-auto text-right truncate grow-1 flex items-center"> + {type === 'schema' ? ( + <Icon + className="ml-auto text-right flex-shrink-0" + component={ + v === 'int' || v === 'float' ? ( + <CarbonStringInteger /> + ) : v === 'string' ? ( + <CarbonStringText /> + ) : v === 'boolean' ? ( + <CarbonBoolean /> + ) : v === 'date' ? ( + <CarbonCalendar /> + ) : v === 'undefined' ? ( + <CarbonUndefined /> + ) : ( + <CarbonUndefined /> + ) + } + color="hsl(var(--clr-sec--400))" + size={24} + /> + ) : v !== undefined && (typeof v !== 'object' || Array.isArray(v)) && v != '' ? ( + <span className="ml-auto text-right truncate">{typeof v === 'number' ? formatNumber(v) : v.toString()}</span> + ) : ( + <div className={`ml-auto mt-auto h-4 w-12 ${styles['diagonal-lines']}`}></div> + )} + </span> + </TooltipTrigger> + <TooltipContent side="right"> + <div className="max-w-[18rem] break-all line-clamp-6"> + {v !== undefined && (typeof v !== 'object' || Array.isArray(v)) && v != '' ? v : 'noData'} + </div> + </TooltipContent> + </div> + </Tooltip> + )) + )} + </div> + </TooltipProvider> + </div> + ); +}; diff --git a/libs/shared/lib/components/VisualizationTooltip/index.tsx b/libs/shared/lib/components/VisualizationTooltip/index.tsx new file mode 100644 index 000000000..868ce59de --- /dev/null +++ b/libs/shared/lib/components/VisualizationTooltip/index.tsx @@ -0,0 +1 @@ +export * from './VisualizationTooltip'; -- GitLab