diff --git a/libs/shared/lib/components/buttons/index.tsx b/libs/shared/lib/components/buttons/index.tsx index a83936dcc4ba79af9c8c6ca8652281a2c3403c9a..c98e59fda4a69d15b76c2ec9c3bd722ff901697b 100644 --- a/libs/shared/lib/components/buttons/index.tsx +++ b/libs/shared/lib/components/buttons/index.tsx @@ -1,6 +1,7 @@ import React, { ReactElement } from 'react'; import styles from './buttons.module.scss'; import Icon, { Sizes } from '../icon'; +import { forwardRef } from 'react'; type ButtonProps = { type?: 'primary' | 'secondary' | 'danger'; @@ -18,98 +19,104 @@ type ButtonProps = { additionalClasses?: string; }; -export function Button({ - type = 'secondary', - variant = 'solid', - label, - size = 'md', - rounded = false, - disabled = false, - onClick, - block = false, - iconComponent, - iconPosition = 'leading', - ariaLabel, - additionalClasses, - children, - ...props -}: ButtonProps & React.HTMLAttributes<HTMLButtonElement>) { - let typeClass = ''; - let variantClass = ''; - let sizeClass = ''; - const blockClass = block ? styles['btn-block'] : ''; - const roundedClass = rounded ? styles['btn-rounded'] : ''; +export const Button = React.forwardRef<HTMLButtonElement, ButtonProps & React.HTMLAttributes<HTMLButtonElement>>( + ( + { + type = 'secondary', + variant = 'solid', + label, + size = 'md', + rounded = false, + disabled = false, + onClick, + block = false, + iconComponent, + iconPosition = 'leading', + ariaLabel, + additionalClasses, + children, + ...props + }, + forwardRef, + ) => { + let typeClass = ''; + let variantClass = ''; + let sizeClass = ''; + const blockClass = block ? styles['btn-block'] : ''; + const roundedClass = rounded ? styles['btn-rounded'] : ''; - switch (type) { - case 'primary': - typeClass = styles['btn-primary']; - break; - case 'secondary': - typeClass = styles['btn-secondary']; - break; - case 'danger': - typeClass = styles['btn-danger']; - break; - default: - return null; - } + switch (type) { + case 'primary': + typeClass = styles['btn-primary']; + break; + case 'secondary': + typeClass = styles['btn-secondary']; + break; + case 'danger': + typeClass = styles['btn-danger']; + break; + default: + return null; + } - switch (variant) { - case 'solid': - variantClass = styles['btn-solid']; - break; - case 'outline': - variantClass = styles['btn-outline']; - break; - case 'ghost': - variantClass = styles['btn-ghost']; - break; - default: - return null; - } + switch (variant) { + case 'solid': + variantClass = styles['btn-solid']; + break; + case 'outline': + variantClass = styles['btn-outline']; + break; + case 'ghost': + variantClass = styles['btn-ghost']; + break; + default: + return null; + } - let iconSize: Sizes = 24; + let iconSize: Sizes = 24; - switch (size) { - case 'xs': - sizeClass = styles['btn-xs']; - iconSize = 16; - break; - case 'sm': - sizeClass = styles['btn-sm']; - iconSize = 20; - break; - case 'md': - sizeClass = styles['btn-md']; - iconSize = 24; - break; - case 'lg': - sizeClass = styles['btn-lg']; - iconSize = 28; - break; - default: - return null; - } + switch (size) { + case 'xs': + sizeClass = styles['btn-xs']; + iconSize = 16; + break; + case 'sm': + sizeClass = styles['btn-sm']; + iconSize = 20; + break; + case 'md': + sizeClass = styles['btn-md']; + iconSize = 24; + break; + case 'lg': + sizeClass = styles['btn-lg']; + iconSize = 28; + break; + default: + return null; + } - const icon = iconComponent ? <Icon component={iconComponent} size={iconSize} /> : null; + const icon = iconComponent ? <Icon component={iconComponent} size={iconSize} /> : null; - const iconOnlyClass = iconComponent && !label && !children ? styles['btn-icon-only'] : ''; + const iconOnlyClass = iconComponent && !label && !children ? styles['btn-icon-only'] : ''; - return ( - <button - className={`${styles.btn} ${typeClass} ${variantClass} ${sizeClass} ${blockClass} ${roundedClass} ${iconOnlyClass} ${additionalClasses}`} - onClick={onClick} - disabled={disabled} - aria-label={ariaLabel} - {...props} - > - {iconPosition === 'leading' && icon} - {label && <span>{label}</span>} - {children && <span>{children}</span>} - {iconPosition === 'trailing' && icon} - </button> - ); -} + return ( + <button + className={`${styles.btn} ${typeClass} ${variantClass} ${sizeClass} ${blockClass} ${roundedClass} ${iconOnlyClass} ${additionalClasses}`} + onClick={onClick} + disabled={disabled} + aria-label={ariaLabel} + ref={forwardRef} + {...props} + > + {iconPosition === 'leading' && icon} + {label && <span>{label}</span>} + {children && <span>{children}</span>} + {iconPosition === 'trailing' && icon} + </button> + ); + }, +); type ButtonGroupProps = { children: React.ReactNode; diff --git a/libs/shared/lib/components/color-mode/index.tsx b/libs/shared/lib/components/color-mode/index.tsx index 4376dd0aa1feee1ff207cf8e2a6e54bf38f74d13..97abb3e04d28af79a1f8f3c03253638d57542a20 100644 --- a/libs/shared/lib/components/color-mode/index.tsx +++ b/libs/shared/lib/components/color-mode/index.tsx @@ -44,7 +44,7 @@ const ColorMode = () => { return ( <TooltipProvider delayDuration={0}> <Tooltip> - <TooltipTrigger> + <TooltipTrigger asChild> <Button variant="ghost" iconComponent={iconComponent} onClick={toggleTheme} /> </TooltipTrigger> <TooltipContent side={'bottom'}> diff --git a/libs/shared/lib/data-access/api/eventBus.tsx b/libs/shared/lib/data-access/api/eventBus.tsx index ffd43445d5fc5fa7da9b5c606d29aeecf793ee1e..4f9ea34c22bb784e49ddb700457d2d3875a9f614 100644 --- a/libs/shared/lib/data-access/api/eventBus.tsx +++ b/libs/shared/lib/data-access/api/eventBus.tsx @@ -43,6 +43,7 @@ import { URLParams, getParam, deleteParam } from './url'; import { setVisualizationState } from '../store/visualizationSlice'; import { isEqual } from 'lodash-es'; import { addSchemaAttributeDimensions } from '../store/schemaSlice'; +import { addError } from '@graphpolaris/shared/lib/data-access/store/configSlice'; export const EventBus = (props: { onRunQuery: Function; onAuthorized: Function }) => { const { login } = useAuth(); @@ -85,7 +86,10 @@ export const EventBus = (props: { onRunQuery: Function; onAuthorized: Function } unsubs.push( wsTestSaveStateConnectionSubscription((data) => { - if (data.status === 'success' && data.saveStateID) dispatch(testedSaveState(data.saveStateID)); + if (data?.status === 'success' && data.saveStateID) dispatch(testedSaveState(data.saveStateID)); + else { + dispatch(addError('DB connection failed')); + } }), ); diff --git a/libs/shared/lib/data-access/authorization/dashboardAlerts.tsx b/libs/shared/lib/data-access/authorization/dashboardAlerts.tsx index 0a396532c1a58e785fd6263e8979a0b2358de15f..93839e9c0dc5d6ac3bfeaaf036d0dad5df225858 100644 --- a/libs/shared/lib/data-access/authorization/dashboardAlerts.tsx +++ b/libs/shared/lib/data-access/authorization/dashboardAlerts.tsx @@ -68,7 +68,7 @@ export const DashboardAlerts = (props: { timer?: number }) => { { message: ( <> - <ErrorOutlineIcon /> Sever Error + <ErrorOutlineIcon /> {config.errors?.[config.errors.length - 1] || 'Sever Error'} </> ), className: 'alert-error', diff --git a/libs/shared/lib/querybuilder/panel/querybuilder.tsx b/libs/shared/lib/querybuilder/panel/querybuilder.tsx index 5a2d623a32a89a8ba036934ba331e006a6864fe7..a594becbcf803fdf197f3e51a68605b346bc116e 100644 --- a/libs/shared/lib/querybuilder/panel/querybuilder.tsx +++ b/libs/shared/lib/querybuilder/panel/querybuilder.tsx @@ -443,7 +443,7 @@ export const QueryBuilderInner = (props: QueryBuilderProps) => { <ControlContainer> <TooltipProvider delayDuration={0}> <Tooltip> - <TooltipTrigger> + <TooltipTrigger asChild> <Button type="secondary" variant="ghost" size="xs" iconComponent={<Fullscreen />} onClick={fitView} /> </TooltipTrigger> <TooltipContent side={'bottom'}> @@ -451,7 +451,7 @@ export const QueryBuilderInner = (props: QueryBuilderProps) => { </TooltipContent> </Tooltip> <Tooltip> - <TooltipTrigger> + <TooltipTrigger asChild> <Button type="secondary" variant="ghost" size="xs" iconComponent={<Delete />} onClick={() => clearAllNodes()} /> </TooltipTrigger> <TooltipContent side={'bottom'}> @@ -459,7 +459,7 @@ export const QueryBuilderInner = (props: QueryBuilderProps) => { </TooltipContent> </Tooltip> <Tooltip> - <TooltipTrigger> + <TooltipTrigger asChild> <Button type="secondary" variant="ghost" @@ -475,7 +475,7 @@ export const QueryBuilderInner = (props: QueryBuilderProps) => { </TooltipContent> </Tooltip> <Tooltip> - <TooltipTrigger> + <TooltipTrigger asChild> <Button type="secondary" variant="ghost" @@ -492,7 +492,7 @@ export const QueryBuilderInner = (props: QueryBuilderProps) => { </TooltipContent> </Tooltip> <Tooltip> - <TooltipTrigger> + <TooltipTrigger asChild> <Button type="secondary" variant="ghost" @@ -511,7 +511,7 @@ export const QueryBuilderInner = (props: QueryBuilderProps) => { </TooltipContent> </Tooltip> <Tooltip> - <TooltipTrigger> + <TooltipTrigger asChild> <Button type="secondary" variant="ghost" @@ -528,7 +528,7 @@ export const QueryBuilderInner = (props: QueryBuilderProps) => { </TooltipContent> </Tooltip> <Tooltip> - <TooltipTrigger> + <TooltipTrigger asChild> <Button type="secondary" variant="ghost" @@ -546,7 +546,7 @@ export const QueryBuilderInner = (props: QueryBuilderProps) => { </TooltipContent> </Tooltip> <Tooltip> - <TooltipTrigger> + <TooltipTrigger asChild> <Button type="secondary" variant="ghost" diff --git a/libs/shared/lib/schema/panel/schema.tsx b/libs/shared/lib/schema/panel/schema.tsx index e9fcbff627892795fb0ce930e75dbd86639f8a5c..37ed7444c2b9b15b1bb6a7add6a02b1296a07cbb 100644 --- a/libs/shared/lib/schema/panel/schema.tsx +++ b/libs/shared/lib/schema/panel/schema.tsx @@ -117,7 +117,7 @@ export const Schema = (props: Props) => { <ControlContainer> <TooltipProvider delayDuration={0}> <Tooltip> - <TooltipTrigger> + <TooltipTrigger asChild> <Button type="secondary" variant="ghost" size="xs" iconComponent={<Fullscreen />} onClick={fitView} /> </TooltipTrigger> <TooltipContent side={'bottom'}> @@ -125,7 +125,7 @@ export const Schema = (props: Props) => { </TooltipContent> </Tooltip> <Tooltip> - <TooltipTrigger> + <TooltipTrigger asChild> <Button type="secondary" variant="ghost" @@ -143,7 +143,7 @@ export const Schema = (props: Props) => { </TooltipContent> </Tooltip> <Tooltip> - <TooltipTrigger> + <TooltipTrigger asChild> <Button type="secondary" variant="ghost" diff --git a/libs/shared/lib/vis/visualizationPanel.tsx b/libs/shared/lib/vis/visualizationPanel.tsx index 14c2245fea1c412e8173054808d0ca22a334b067..ab722fc2c3c9fadaa52e4bb66ce61fe440aed42b 100644 --- a/libs/shared/lib/vis/visualizationPanel.tsx +++ b/libs/shared/lib/vis/visualizationPanel.tsx @@ -40,7 +40,7 @@ export const VisualizationPanel = () => { <ControlContainer> <TooltipProvider delayDuration={0}> <Tooltip disabled={showVisSettings}> - <TooltipTrigger> + <TooltipTrigger asChild> <Button type="secondary" variant="ghost" @@ -57,7 +57,7 @@ export const VisualizationPanel = () => { </TooltipContent> </Tooltip> <Tooltip> - <TooltipTrigger> + <TooltipTrigger asChild> <Button type="secondary" variant="ghost"