diff --git a/package.json b/package.json
index d32bfa0e..44ed9d60 100644
--- a/package.json
+++ b/package.json
@@ -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",
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 905f5b9f..20ef2841 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -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
diff --git a/src/client/components/AppStatus/AppStatus.tsx b/src/client/components/AppStatus/AppStatus.tsx
index d687a9bc..c08d9559 100644
--- a/src/client/components/AppStatus/AppStatus.tsx
+++ b/src/client/components/AppStatus/AppStatus.tsx
@@ -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 (
-
-
- {!lite && {formattedStatus}}
-
+ <>
+ {lite && (
+
+ {formattedStatus}
+
+ )}
+
+
+ {!lite && {formattedStatus}}
+
+ >
);
};
diff --git a/src/client/components/AppTile/AppTile.tsx b/src/client/components/AppTile/AppTile.tsx
index 8f9cdd73..e8e44580 100644
--- a/src/client/components/AppTile/AppTile.tsx
+++ b/src/client/components/AppTile/AppTile.tsx
@@ -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
{updateAvailable && (
-
-
-
+ <>
+ Update available
+
+
+
+ >
)}
diff --git a/src/client/components/Layout/Layout.tsx b/src/client/components/Layout/Layout.tsx
index 7e41962b..c8b28d39 100644
--- a/src/client/components/Layout/Layout.tsx
+++ b/src/client/components/Layout/Layout.tsx
@@ -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 = ({ children, breadcrumbs, title, actions
{`${title} - Tipi`}
-
diff --git a/src/client/components/ui/Header/Header.test.tsx b/src/client/components/ui/Header/Header.test.tsx
index e87cd9d7..a09158b3 100644
--- a/src/client/components/ui/Header/Header.test.tsx
+++ b/src/client/components/ui/Header/Header.test.tsx
@@ -5,8 +5,7 @@ import { Header } from './Header';
describe('Header', () => {
it('renders without crashing', () => {
- const { container } = render();
- expect(container).toBeInTheDocument();
+ render();
});
it('renders the brand logo', () => {
@@ -16,22 +15,22 @@ describe('Header', () => {
});
it('renders the dark mode toggle', () => {
- const { container } = render();
- const darkModeToggle = container.querySelector('[data-tip="Dark mode"]');
+ render();
+ const darkModeToggle = screen.getByTestId('dark-mode-toggle');
expect(darkModeToggle).toContainElement(screen.getByTestId('icon-moon'));
});
it('renders the light mode toggle', () => {
- const { container } = render();
- const lightModeToggle = container.querySelector('[data-tip="Light mode"]');
+ render();
+ 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();
- const darkModeToggle = container.querySelector('[data-tip="Dark mode"]');
+ render();
+ 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();
- const lightModeToggle = container.querySelector('[data-tip="Light mode"]');
+ render();
+ 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();
- const logoutButton = container.querySelector('[data-tip="Log out"]');
+ render();
+ const logoutButton = screen.getByTestId('logout-button');
fireEvent.click(logoutButton as Element);
await waitFor(() => {
diff --git a/src/client/components/ui/Header/Header.tsx b/src/client/components/ui/Header/Header.tsx
index 904e7191..b2963391 100644
--- a/src/client/components/ui/Header/Header.tsx
+++ b/src/client/components/ui/Header/Header.tsx
@@ -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 = ({ isUpdateAvailable }) => {
-
-
setDarkMode(true)} role="button" aria-hidden="true" className="nav-link px-0 hide-theme-dark cursor-pointer" data-tip="Dark mode">
+
+
Dark mode
+
setDarkMode(true)} role="button" aria-hidden="true" className="darkMode nav-link px-0 hide-theme-dark cursor-pointer" data-testid="dark-mode-toggle">
-
setDarkMode(false)} aria-hidden="true" className="nav-link px-0 hide-theme-light cursor-pointer" data-tip="Light mode">
+
Light mode
+
setDarkMode(false)} aria-hidden="true" className="lightMode nav-link px-0 hide-theme-light cursor-pointer" data-testid="light-mode-toggle">
-
logout.mutate()} tabIndex={0} onKeyPress={() => logout.mutate()} role="button" className="nav-link px-0 cursor-pointer" data-tip="Log out">
+
Log out
+
logout.mutate()} tabIndex={0} onKeyPress={() => logout.mutate()} role="button" className="logOut nav-link px-0 cursor-pointer" data-testid="logout-button">
diff --git a/src/pages/_app.tsx b/src/pages/_app.tsx
index 77f2b1f3..3e8a1043 100644
--- a/src/pages/_app.tsx
+++ b/src/pages/_app.tsx
@@ -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';