refactor: upgrade react-tooltip to v5

This commit is contained in:
Nicolas Meienberger 2023-04-08 12:23:33 +02:00 committed by Nicolas Meienberger
parent adbe91be46
commit 2f0f4bd498
8 changed files with 53 additions and 41 deletions

View file

@ -62,7 +62,7 @@
"react-hook-form": "^7.43.7",
"react-markdown": "^8.0.3",
"react-select": "^5.6.1",
"react-tooltip": "^4.4.3",
"react-tooltip": "^5.10.5",
"redis": "^4.6.5",
"remark-breaks": "^3.0.2",
"remark-gfm": "^3.0.1",

View file

@ -101,8 +101,8 @@ dependencies:
specifier: ^5.6.1
version: 5.7.0(@types/react@18.0.28)(react-dom@18.2.0)(react@18.2.0)
react-tooltip:
specifier: ^4.4.3
version: 4.5.1(react-dom@18.2.0)(react@18.2.0)
specifier: ^5.10.5
version: 5.10.5(react-dom@18.2.0)(react@18.2.0)
redis:
specifier: ^4.6.5
version: 4.6.5
@ -3163,6 +3163,10 @@ packages:
resolution: {integrity: sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA==}
dev: true
/classnames@2.3.2:
resolution: {integrity: sha512-CSbhY4cFEJRe6/GQzIk5qXZ4Jeg5pcsP7b5peFSDpffpe1cqjASH/n9UTjBwOp6XpMSTwQ8Za2K5V02ueA7Tmw==}
dev: false
/cli-cursor@3.1.0:
resolution: {integrity: sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==}
engines: {node: '>=8'}
@ -7330,17 +7334,16 @@ packages:
tslib: 2.5.0
dev: false
/react-tooltip@4.5.1(react-dom@18.2.0)(react@18.2.0):
resolution: {integrity: sha512-Zo+CSFUGXar1uV+bgXFFDe7VeS2iByeIp5rTgTcc2HqtuOS5D76QapejNNfx320MCY91TlhTQat36KGFTqgcvw==}
engines: {npm: '>=6.13'}
/react-tooltip@5.10.5(react-dom@18.2.0)(react@18.2.0):
resolution: {integrity: sha512-3bi4UtoPSdaQh0R17B3vMPhNFiATpAbXIV8AqlHqrrIdqo33OJyxuPHtgborw3KXVQ5a6iyyAmCY8ztjUB4CrA==}
peerDependencies:
react: '>=16.0.0'
react-dom: '>=16.0.0'
react: '>=16.14.0'
react-dom: '>=16.14.0'
dependencies:
prop-types: 15.8.1
'@floating-ui/dom': 1.2.1
classnames: 2.3.2
react: 18.2.0
react-dom: 18.2.0(react@18.2.0)
uuid: 7.0.3
dev: false
/react-transition-group@4.4.5(react-dom@18.2.0)(react@18.2.0):
@ -8424,11 +8427,6 @@ packages:
engines: {node: '>= 0.4.0'}
dev: false
/uuid@7.0.3:
resolution: {integrity: sha512-DPSke0pXhTZgoF/d+WSt2QaKMCFSfx7QegxEWT+JOuHF5aWrKEn0G+ztjuJg/gG8/ItK+rbPCD/yNv8yyih6Cg==}
hasBin: true
dev: false
/uuid@8.3.2:
resolution: {integrity: sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==}
hasBin: true

View file

@ -1,10 +1,11 @@
import clsx from 'clsx';
import React from 'react';
import { Tooltip } from 'react-tooltip';
import * as AppTypes from '../../core/types';
import styles from './AppStatus.module.scss';
export const AppStatus: React.FC<{ status: AppTypes.AppStatus; lite?: boolean }> = ({ status, lite }) => {
const formattedStatus = `${status[0]}${status.substring(1, status.length).toLowerCase()}`;
const formattedStatus = `${status[0]?.toUpperCase()}${status.substring(1, status.length).toLowerCase()}`;
const classes = clsx('status-dot status-gray', {
'status-dot-animated status-green': status === 'running',
@ -12,9 +13,16 @@ export const AppStatus: React.FC<{ status: AppTypes.AppStatus; lite?: boolean }>
});
return (
<div data-place="top" data-tip={lite && formattedStatus} className="d-flex align-items-center">
<span className={classes} />
{!lite && <span className={clsx(styles.text, 'ms-2 text-muted')}>{formattedStatus}</span>}
</div>
<>
{lite && (
<Tooltip anchorSelect=".appStatus" place="top">
{formattedStatus}
</Tooltip>
)}
<div className="appStatus d-flex align-items-center">
<span className={classes} />
{!lite && <span className={clsx(styles.text, 'ms-2 text-muted')}>{formattedStatus}</span>}
</div>
</>
);
};

View file

@ -1,6 +1,7 @@
import Link from 'next/link';
import React from 'react';
import { IconDownload } from '@tabler/icons-react';
import { Tooltip } from 'react-tooltip';
import { AppStatus } from '../AppStatus';
import { AppLogo } from '../AppLogo/AppLogo';
import { limitText } from '../../modules/AppStore/helpers/table.helpers';
@ -30,9 +31,12 @@ export const AppTile: React.FC<{ app: AppTileInfo; status: AppStatusEnum; update
</div>
</div>
{updateAvailable && (
<div data-tip="Update available" className="ribbon bg-green ribbon-top">
<IconDownload size={20} />
</div>
<>
<Tooltip anchorSelect=".updateAvailable">Update available</Tooltip>
<div className="updateAvailable ribbon bg-green ribbon-top">
<IconDownload size={20} />
</div>
</>
)}
</Link>
</div>

View file

@ -2,7 +2,6 @@ import Head from 'next/head';
import Link from 'next/link';
import React, { useEffect } from 'react';
import clsx from 'clsx';
import ReactTooltip from 'react-tooltip';
import semver from 'semver';
import { useRouter } from 'next/router';
import { Header } from '../ui/Header';
@ -61,7 +60,6 @@ export const Layout: React.FC<IProps> = ({ children, breadcrumbs, title, actions
<Head>
<title>{`${title} - Tipi`}</title>
</Head>
<ReactTooltip offset={{ right: 1 }} effect="solid" place="bottom" />
<Header isUpdateAvailable={!isLatest} />
<div className="page-wrapper">
<div className="page-header d-print-none">

View file

@ -5,8 +5,7 @@ import { Header } from './Header';
describe('Header', () => {
it('renders without crashing', () => {
const { container } = render(<Header />);
expect(container).toBeInTheDocument();
render(<Header />);
});
it('renders the brand logo', () => {
@ -16,22 +15,22 @@ describe('Header', () => {
});
it('renders the dark mode toggle', () => {
const { container } = render(<Header />);
const darkModeToggle = container.querySelector('[data-tip="Dark mode"]');
render(<Header />);
const darkModeToggle = screen.getByTestId('dark-mode-toggle');
expect(darkModeToggle).toContainElement(screen.getByTestId('icon-moon'));
});
it('renders the light mode toggle', () => {
const { container } = render(<Header />);
const lightModeToggle = container.querySelector('[data-tip="Light mode"]');
render(<Header />);
const lightModeToggle = screen.getByTestId('light-mode-toggle');
expect(lightModeToggle).toContainElement(screen.getByTestId('icon-sun'));
});
it('Should toggle the dark mode on click of the dark mode toggle', () => {
const { result } = renderHook(() => useUIStore());
const { container } = render(<Header />);
const darkModeToggle = container.querySelector('[data-tip="Dark mode"]');
render(<Header />);
const darkModeToggle = screen.getByTestId('dark-mode-toggle');
fireEvent.click(darkModeToggle as Element);
expect(result.current.darkMode).toBe(true);
@ -40,8 +39,8 @@ describe('Header', () => {
it('Should toggle the dark mode on click of the light mode toggle', () => {
const { result } = renderHook(() => useUIStore());
const { container } = render(<Header />);
const lightModeToggle = container.querySelector('[data-tip="Light mode"]');
render(<Header />);
const lightModeToggle = screen.getByTestId('light-mode-toggle');
fireEvent.click(lightModeToggle as Element);
expect(result.current.darkMode).toBe(false);
@ -49,8 +48,8 @@ describe('Header', () => {
it('Should remove the token from local storage on logout', async () => {
localStorage.setItem('token', 'token');
const { container } = render(<Header />);
const logoutButton = container.querySelector('[data-tip="Log out"]');
render(<Header />);
const logoutButton = screen.getByTestId('logout-button');
fireEvent.click(logoutButton as Element);
await waitFor(() => {

View file

@ -4,6 +4,7 @@ import Image from 'next/image';
import clsx from 'clsx';
import Link from 'next/link';
import { useRouter } from 'next/router';
import { Tooltip } from 'react-tooltip';
import { getUrl } from '../../../core/helpers/url-helpers';
import { useUIStore } from '../../../state/uiStore';
import { NavBar } from '../NavBar';
@ -62,14 +63,17 @@ export const Header: React.FC<IProps> = ({ isUpdateAvailable }) => {
</a>
</div>
</div>
<div className="d-flex">
<div onClick={() => setDarkMode(true)} role="button" aria-hidden="true" className="nav-link px-0 hide-theme-dark cursor-pointer" data-tip="Dark mode">
<div style={{ zIndex: 1 }} className="d-flex">
<Tooltip anchorSelect=".darkMode">Dark mode</Tooltip>
<div onClick={() => setDarkMode(true)} role="button" aria-hidden="true" className="darkMode nav-link px-0 hide-theme-dark cursor-pointer" data-testid="dark-mode-toggle">
<IconMoon data-testid="icon-moon" size={20} />
</div>
<div onClick={() => setDarkMode(false)} aria-hidden="true" className="nav-link px-0 hide-theme-light cursor-pointer" data-tip="Light mode">
<Tooltip anchorSelect=".lightMode">Light mode</Tooltip>
<div onClick={() => setDarkMode(false)} aria-hidden="true" className="lightMode nav-link px-0 hide-theme-light cursor-pointer" data-testid="light-mode-toggle">
<IconSun data-testid="icon-sun" size={20} />
</div>
<div onClick={() => logout.mutate()} tabIndex={0} onKeyPress={() => logout.mutate()} role="button" className="nav-link px-0 cursor-pointer" data-tip="Log out">
<Tooltip anchorSelect=".logOut">Log out</Tooltip>
<div onClick={() => logout.mutate()} tabIndex={0} onKeyPress={() => logout.mutate()} role="button" className="logOut nav-link px-0 cursor-pointer" data-testid="logout-button">
<IconLogout size={20} />
</div>
</div>

View file

@ -4,6 +4,7 @@ import type { AppProps } from 'next/app';
import Head from 'next/head';
import '../client/styles/global.css';
import '../client/styles/global.scss';
import 'react-tooltip/dist/react-tooltip.css';
import { useUIStore } from '../client/state/uiStore';
import { ToastProvider } from '../client/components/hoc/ToastProvider';
import { StatusProvider } from '../client/components/hoc/StatusProvider';