From 6ddb89864eb84e579704847f8695277e091a1760 Mon Sep 17 00:00:00 2001 From: Leonardo <leomilho@gmail.com> Date: Thu, 11 Jul 2024 19:05:11 +0200 Subject: [PATCH] chore: fixes to merge --- .../CardToolTipVis/VisualizationTooltip.tsx | 140 +++++++++++++++++ .../CardToolTipVis/cardtooltipvis.stories.tsx | 16 +- .../lib/components/CardToolTipVis/index.tsx | 143 +----------------- .../pills/nodes/entity/SchemaEntityPill.tsx | 4 +- .../pills/nodes/entity/SchemaEntityPopup.tsx | 86 ----------- .../nodes/relation/SchemaRelationPill.tsx | 4 +- 6 files changed, 153 insertions(+), 240 deletions(-) create mode 100644 libs/shared/lib/components/CardToolTipVis/VisualizationTooltip.tsx delete mode 100644 libs/shared/lib/schema/pills/nodes/entity/SchemaEntityPopup.tsx diff --git a/libs/shared/lib/components/CardToolTipVis/VisualizationTooltip.tsx b/libs/shared/lib/components/CardToolTipVis/VisualizationTooltip.tsx new file mode 100644 index 000000000..53bebb390 --- /dev/null +++ b/libs/shared/lib/components/CardToolTipVis/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 './cardtooltipvis.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/CardToolTipVis/cardtooltipvis.stories.tsx b/libs/shared/lib/components/CardToolTipVis/cardtooltipvis.stories.tsx index 1bc4cef9b..ed1149af7 100644 --- a/libs/shared/lib/components/CardToolTipVis/cardtooltipvis.stories.tsx +++ b/libs/shared/lib/components/CardToolTipVis/cardtooltipvis.stories.tsx @@ -1,20 +1,20 @@ import React, { useState } from 'react'; import type { Meta, StoryObj } from '@storybook/react'; -import { CardToolTipVis, CardToolTipVisProps } from '@graphpolaris/shared/lib/components/CardToolTipVis'; +import { VisualizationTooltip, CardToolTipVisProps } from '@graphpolaris/shared/lib/components/CardToolTipVis'; -const metaCardToolTipVis: Meta<typeof CardToolTipVis> = { - component: CardToolTipVis, +const metaCardToolTipVis: Meta<typeof VisualizationTooltip> = { + component: VisualizationTooltip, title: 'Components/CardToolTipVis', }; export default metaCardToolTipVis; -type Story = StoryObj<typeof CardToolTipVis>; +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"> - <CardToolTipVis {...args} /> + <VisualizationTooltip {...args} /> </div> ); }, @@ -36,7 +36,7 @@ export const SchemaRelationship: Story = { render: (args) => { return ( <div className="w-1/4 my-10 m-auto flex items-center justify-center"> - <CardToolTipVis {...args} /> + <VisualizationTooltip {...args} /> </div> ); }, @@ -62,7 +62,7 @@ export const PopUpVis: Story = { render: (args) => { return ( <div className="w-1/4 my-10 m-auto flex items-center justify-center"> - <CardToolTipVis {...args} /> + <VisualizationTooltip {...args} /> </div> ); }, @@ -74,7 +74,7 @@ export const PopUpVis: Story = { name: 'Charlotte Henry', born: {}, imdbRank: 21213, - imdbVotesddddddddddddddddddddd: 1213, + imdbVotes: 1213, poster: 'https://image.tmdb.org/t/p/w440_and_h660_face/kTKiREs37qd8GUlNI4Koiupwy6W.jpg', tmdbId: '94105', country: undefined, diff --git a/libs/shared/lib/components/CardToolTipVis/index.tsx b/libs/shared/lib/components/CardToolTipVis/index.tsx index e12ff470c..868ce59de 100644 --- a/libs/shared/lib/components/CardToolTipVis/index.tsx +++ b/libs/shared/lib/components/CardToolTipVis/index.tsx @@ -1,142 +1 @@ -import React from 'react'; -import { Icon } from '@graphpolaris/shared/lib/components/icon'; -import { Numbers, Close } from '@mui/icons-material'; -import styles from './cardtooltipvis.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'; - -import { Button } from '@graphpolaris/shared/lib/components/buttons'; - -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 CardToolTipVis: 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> - ); -}; +export * from './VisualizationTooltip'; diff --git a/libs/shared/lib/schema/pills/nodes/entity/SchemaEntityPill.tsx b/libs/shared/lib/schema/pills/nodes/entity/SchemaEntityPill.tsx index 3567bb22d..3bf2158a5 100644 --- a/libs/shared/lib/schema/pills/nodes/entity/SchemaEntityPill.tsx +++ b/libs/shared/lib/schema/pills/nodes/entity/SchemaEntityPill.tsx @@ -5,7 +5,7 @@ import { QueryElementTypes } from '@graphpolaris/shared/lib/querybuilder'; import { SchemaNode } from '../../../model'; import { EntityPill } from '@graphpolaris/shared/lib/components'; import { Tooltip, TooltipContent, TooltipTrigger } from '@graphpolaris/shared/lib/components/tooltip'; -import { CardToolTipVis, CardToolTipVisProps } from '@graphpolaris/shared/lib/components/CardToolTipVis'; +import { VisualizationTooltip, CardToolTipVisProps } from '@graphpolaris/shared/lib/components/CardToolTipVis'; export const SchemaEntityPill = React.memo(({ id, selected, data }: NodeProps<SchemaReactflowNodeWithFunctions>) => { const [openPopup, setOpenPopup] = useState(false); @@ -58,7 +58,7 @@ export const SchemaEntityPill = React.memo(({ id, selected, data }: NodeProps<Sc <TooltipTrigger /> <TooltipContent side="right"> <div> - <CardToolTipVis + <VisualizationTooltip type="schema" typeOfSchema="node" name={data.name} diff --git a/libs/shared/lib/schema/pills/nodes/entity/SchemaEntityPopup.tsx b/libs/shared/lib/schema/pills/nodes/entity/SchemaEntityPopup.tsx deleted file mode 100644 index 9514679eb..000000000 --- a/libs/shared/lib/schema/pills/nodes/entity/SchemaEntityPopup.tsx +++ /dev/null @@ -1,86 +0,0 @@ -/** - * This program has been developed by students from the bachelor Computer Science at - * Utrecht University within the Software Project course. - * © Copyright Utrecht University (Department of Information and Computing Sciences) - */ - -/* istanbul ignore file */ -/* The comment above was added so the code coverage wouldn't count this file towards code coverage. - * We do not test components/renderfunctions/styling files. - * See testing plan for more details.*/ - -import { FormBody, FormCard, FormControl, FormHBar, FormTitle } from '@graphpolaris/shared/lib/components/forms'; -import { SchemaReactflowEntity } from '@graphpolaris/shared/lib/schema/model'; -import { FormEvent } from 'react'; - -export type SchemaEntityPopupProps = { - data: SchemaReactflowEntity; - onClose: () => void; -}; - -/** - * NodeQualityEntityPopupNode is the node that represents the popup that shows the node quality for an entity - * @param data Input data of type NodeQualityDataForEntities, which is for the popup. - */ -export const SchemaEntityPopup = (props: SchemaEntityPopupProps) => { - function submit() { - // dispatch(setSchemaSettings(state)); - props.onClose(); - } - - return ( - // <FormDiv hAnchor="left"> - <> - {/* - <FormCard> - <FormBody - onSubmit={(e: FormEvent<HTMLFormElement>) => { - e.preventDefault(); - submit(); - }} - > - <FormTitle - title="Node Statistics" - // title={props.data.name} - onClose={props.onClose} - /> - <FormHBar /> - - <span className="px-5 pt-2"> - <span>Name</span> - <span className="float-right break-all text-wrap text-pretty font-light font-mono">{props.data.name}</span> - </span> - - <FormHBar /> - - <span className="px-5 pt-2"> - <span>Attributes</span> - <span className="float-right font-light font-mono">{props.data.attributes.length}</span> - </span> - - {props.data.attributes.map((attribute: any) => { - return ( - <div key={attribute.name} className="px-5 pt-1"> - <span>{attribute.name}</span> - <span className="float-right font-light font-mono">{attribute.type}</span> - </div> - ); - })} - <FormHBar /> - - <FormControl> - <button - className="btn btn-outline btn-accent border-0 btn-sm p-0 m-0 text-[0.8rem] mb-2 mx-2.5 min-h-0 h-5" - onClick={() => { - submit(); - }} - > - Close - </button> - </FormControl> - </FormBody> - </FormCard> - */} - </> - ); -}; diff --git a/libs/shared/lib/schema/pills/nodes/relation/SchemaRelationPill.tsx b/libs/shared/lib/schema/pills/nodes/relation/SchemaRelationPill.tsx index ac346ae1e..10643f810 100644 --- a/libs/shared/lib/schema/pills/nodes/relation/SchemaRelationPill.tsx +++ b/libs/shared/lib/schema/pills/nodes/relation/SchemaRelationPill.tsx @@ -8,7 +8,7 @@ import { SchemaEdge } from '../../../model'; import { RelationPill } from '@graphpolaris/shared/lib/components'; import { Tooltip, TooltipContent, TooltipTrigger } from '@graphpolaris/shared/lib/components/tooltip'; -import { CardToolTipVis, CardToolTipVisProps } from '@graphpolaris/shared/lib/components/CardToolTipVis'; +import { VisualizationTooltip, CardToolTipVisProps } from '@graphpolaris/shared/lib/components/CardToolTipVis'; export const SchemaRelationPill = React.memo(({ id, selected, data, ...props }: NodeProps<SchemaReactflowRelationWithFunctions>) => { const [openPopup, setOpenPopup] = useState(false); @@ -66,7 +66,7 @@ export const SchemaRelationPill = React.memo(({ id, selected, data, ...props }: <TooltipTrigger /> <TooltipContent side="top"> <div> - <CardToolTipVis + <VisualizationTooltip type="schema" typeOfSchema="relationship" name={data.collection} -- GitLab