From d30f5ccae09c62f4deaedef332a378526843b1bd Mon Sep 17 00:00:00 2001 From: Nouha-ElAbrouki <97687698+Noha-ElAbrouki@users.noreply.github.com> Date: Wed, 24 Aug 2022 14:21:04 +0200 Subject: [PATCH] enh(Resources/header): Display the 2 access pictograms logs and report on details panel (#11478) * Display the 2 access pictograms logs and report on details panel * Update www/front_src/src/Resources/Details/Header.tsx Co-authored-by: Tom Darneix * Update www/front_src/src/Resources/Details/Header.tsx Co-authored-by: Tom Darneix * fixes * fix test * fix eslint * update style * update style * add test * use divider insead of border css * Update www/front_src/src/Resources/Details/Header.tsx Co-authored-by: Tom Darneix * Update www/front_src/src/Resources/Details/index.test.tsx Co-authored-by: Bruno d'Auria Co-authored-by: Tom Darneix Co-authored-by: Bruno d'Auria --- .../src/Resources/Details/Header.tsx | 82 ++++++++++++---- .../Resources/Details/ShortcutsTooltip.tsx | 94 ------------------- .../src/Resources/Details/index.test.tsx | 36 +++---- www/front_src/src/Resources/helpers.ts | 16 ++++ 4 files changed, 101 insertions(+), 127 deletions(-) delete mode 100644 www/front_src/src/Resources/Details/ShortcutsTooltip.tsx create mode 100644 www/front_src/src/Resources/helpers.ts diff --git a/www/front_src/src/Resources/Details/Header.tsx b/www/front_src/src/Resources/Details/Header.tsx index 047a46acd1d..1e43d297f5a 100644 --- a/www/front_src/src/Resources/Details/Header.tsx +++ b/www/front_src/src/Resources/Details/Header.tsx @@ -1,5 +1,6 @@ import { useTranslation } from 'react-i18next'; import { hasPath, isNil, not, path, prop } from 'ramda'; +import { useNavigate } from 'react-router-dom'; import { Grid, @@ -12,7 +13,10 @@ import { import makeStyles from '@mui/styles/makeStyles'; import CopyIcon from '@mui/icons-material/FileCopy'; import SettingsIcon from '@mui/icons-material/Settings'; +import LogsIcon from '@mui/icons-material/Assignment'; +import ReportIcon from '@mui/icons-material/Assessment'; import { CreateCSSProperties } from '@mui/styles'; +import Divider from '@mui/material/Divider'; import { StatusChip, @@ -26,13 +30,14 @@ import { labelConfigure, labelCopyLink, labelLinkCopied, - labelShortcuts, + labelViewLogs, + labelViewReport, labelSomethingWentWrong, } from '../translatedLabels'; import { Parent, ResourceUris } from '../models'; +import { replaceBasename } from '../helpers'; import SelectableResourceName from './tabs/Details/SelectableResourceName'; -import ShortcutsTooltip from './ShortcutsTooltip'; import { DetailsSectionProps } from '.'; @@ -41,15 +46,23 @@ interface MakeStylesProps { } const useStyles = makeStyles((theme) => ({ + containerIcons: { + alignItems: 'center', + display: 'flex', + }, + divider: { + borderColor: theme.palette.text.secondary, + margin: theme.spacing(1, 0.5), + }, header: ({ displaySeverity }): CreateCSSProperties => ({ alignItems: 'center', display: 'grid', gridGap: theme.spacing(2), gridTemplateColumns: `${ displaySeverity ? 'auto' : '' - } auto minmax(0, 1fr) auto auto`, + } auto minmax(0, 1fr) auto`, height: 43, - padding: theme.spacing(0, 1), + padding: theme.spacing(0, 2.5, 0, 1), }), parent: { alignItems: 'center', @@ -57,6 +70,9 @@ const useStyles = makeStyles((theme) => ({ gridGap: theme.spacing(1), gridTemplateColumns: 'auto minmax(0, 1fr)', }, + report: { + marginLeft: theme.spacing(0.5), + }, resourceName: { alignItems: 'center', columnGap: theme.spacing(1), @@ -108,6 +124,7 @@ const Header = ({ details, onSelectParent }: Props): JSX.Element => { displaySeverity: not(isNil(details?.severity)), }); const { t } = useTranslation(); + const navigate = useNavigate(); const { copy } = useCopyToClipboard({ errorMessage: t(labelSomethingWentWrong), @@ -116,6 +133,19 @@ const Header = ({ details, onSelectParent }: Props): JSX.Element => { const copyLink = (): Promise => copy(window.location.href); + const navigateToResourceUris = ( + category: keyof ResourceUris, + ): (() => void) => { + return (): void => { + const url = replaceBasename({ + endpoint: prop(category, resourceUris) || '', + newWord: '/', + }); + + navigate(`${url}`); + }; + }; + if (details === undefined) { return ; } @@ -194,19 +224,37 @@ const Header = ({ details, onSelectParent }: Props): JSX.Element => { )} - - - - +
+ + + + + + + + + + +
); }; diff --git a/www/front_src/src/Resources/Details/ShortcutsTooltip.tsx b/www/front_src/src/Resources/Details/ShortcutsTooltip.tsx deleted file mode 100644 index 804275ca452..00000000000 --- a/www/front_src/src/Resources/Details/ShortcutsTooltip.tsx +++ /dev/null @@ -1,94 +0,0 @@ -import { isNil, prop } from 'ramda'; -import { useTranslation } from 'react-i18next'; - -import MoreHorizIcon from '@mui/icons-material/MoreHoriz'; -import LogsIcon from '@mui/icons-material/Assignment'; -import ReportIcon from '@mui/icons-material/Assessment'; -import { - Link, - List, - ListItem, - ListItemIcon, - ListItemText, - Tooltip, -} from '@mui/material'; -import makeStyles from '@mui/styles/makeStyles'; - -import { PopoverMenu } from '@centreon/ui'; - -import { ResourceUris } from '../models'; -import { - labelActionNotPermitted, - labelShortcuts, - labelViewLogs, - labelViewReport, -} from '../translatedLabels'; - -interface Props { - resourceUris: ResourceUris; -} - -const useStyles = makeStyles((theme) => ({ - iconContainer: { - minWidth: theme.spacing(4.5), - }, - link: { - display: 'contents', - }, -})); - -const ShortcutsTooltip = ({ resourceUris }: Props): JSX.Element => { - const classes = useStyles(); - const { t } = useTranslation(); - - const shortcuts = [ - { - Icon: LogsIcon, - id: 'Logs', - name: labelViewLogs, - uri: prop('logs', resourceUris), - }, - { - Icon: ReportIcon, - id: 'Reporting', - name: labelViewReport, - uri: prop('reporting', resourceUris), - }, - ]; - - return ( - } - title={t(labelShortcuts)} - > - {(): JSX.Element => ( - - {shortcuts.map(({ Icon, uri, name, id }) => ( - -
- - - - - - {t(name)} - - -
-
- ))} -
- )} -
- ); -}; - -export default ShortcutsTooltip; diff --git a/www/front_src/src/Resources/Details/index.test.tsx b/www/front_src/src/Resources/Details/index.test.tsx index c7ad58a0e20..2a5efe42f2e 100644 --- a/www/front_src/src/Resources/Details/index.test.tsx +++ b/www/front_src/src/Resources/Details/index.test.tsx @@ -43,9 +43,9 @@ import { labelCommand, labelComment, labelConfigure, + labelDetails, labelViewLogs, labelViewReport, - labelDetails, labelCopyLink, labelServices, labelFqdn, @@ -62,7 +62,6 @@ import { labelAvg, labelCompactTimePeriod, labelCheck, - labelShortcuts, labelMonitoringServer, labelToday, labelYesterday, @@ -575,6 +574,12 @@ const renderDetails = (): RenderResult => render(); const mockedLocalStorageGetItem = jest.fn(); const mockedLocalStorageSetItem = jest.fn(); +const mockedNavigate = jest.fn(); + +jest.mock('react-router-dom', () => ({ + ...jest.requireActual('react-router-dom'), + useNavigate: (): jest.Mock => mockedNavigate, +})); Storage.prototype.getItem = mockedLocalStorageGetItem; Storage.prototype.setItem = mockedLocalStorageSetItem; @@ -986,15 +991,15 @@ describe(Details, () => { ); }); - it('displays the shortcut links when the More icon is clicked', async () => { + it('navigates to logs and report pages when the corresponding icons are clicked', async () => { mockedAxios.get.mockResolvedValueOnce({ data: { ...retrievedDetails, links: { ...retrievedDetails.links, uris: { - logs: '/logs', - reporting: '/reporting', + logs: 'logs', + reporting: 'reporting', }, }, }, @@ -1004,26 +1009,25 @@ describe(Details, () => { { name: 'details', value: serviceDetailsUrlParameters }, ]); - const { getByLabelText, getAllByLabelText } = renderDetails(); + const { getByLabelText, getByTestId } = renderDetails(); await waitFor(() => { expect(mockedAxios.get).toHaveBeenCalled(); }); await waitFor(() => - expect(getByLabelText(labelShortcuts)).toBeInTheDocument(), + expect(getByLabelText(labelViewLogs)).toBeInTheDocument(), ); - userEvent.click(getByLabelText(labelShortcuts).firstChild as HTMLElement); + expect(getByLabelText(labelViewReport)).toBeInTheDocument(); - expect(getAllByLabelText(labelViewLogs)[0]).toHaveAttribute( - 'href', - '/logs', - ); - expect(getAllByLabelText(labelViewReport)[0]).toHaveAttribute( - 'href', - '/reporting', - ); + userEvent.click(getByTestId(labelViewLogs)); + + expect(mockedNavigate).toHaveBeenCalledWith('/logs'); + + userEvent.click(getByTestId(labelViewReport)); + + expect(mockedNavigate).toHaveBeenCalledWith('/reporting'); }); it('sets the details according to the details URL query parameter when given', async () => { diff --git a/www/front_src/src/Resources/helpers.ts b/www/front_src/src/Resources/helpers.ts new file mode 100644 index 00000000000..25a4d1afbd3 --- /dev/null +++ b/www/front_src/src/Resources/helpers.ts @@ -0,0 +1,16 @@ +interface ReplaceBasename { + endpoint: string; + newWord: string; +} + +export const replaceBasename = ({ + newWord, + endpoint, +}: ReplaceBasename): string => { + const basename = + (document + .getElementsByTagName('base')[0] + ?.getAttribute('href') as string) || ''; + + return endpoint.replace(basename, newWord); +};