From a8da74df560da6ace190f646fb3b538480bc10f0 Mon Sep 17 00:00:00 2001 From: Dominique Clarke Date: Thu, 22 Jul 2021 21:58:22 -0400 Subject: [PATCH] [Uptime] monitor list layout fix (#106159) * update monitor list component to hide downtown history and accordion toggle in medium and large screens * force page headings with flex content to wrap * adjust types * adjust variable naming for uptime monitor list Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- .../__snapshots__/monitor_list.test.tsx.snap | 6 +- .../monitor_list/monitor_list.test.tsx | 67 +++++ .../overview/monitor_list/monitor_list.tsx | 229 ++++++++++-------- x-pack/plugins/uptime/public/routes.tsx | 11 +- 4 files changed, 212 insertions(+), 101 deletions(-) diff --git a/x-pack/plugins/uptime/public/components/overview/monitor_list/__snapshots__/monitor_list.test.tsx.snap b/x-pack/plugins/uptime/public/components/overview/monitor_list/__snapshots__/monitor_list.test.tsx.snap index a4fcb141d454b..e6e7250dd5533 100644 --- a/x-pack/plugins/uptime/public/components/overview/monitor_list/__snapshots__/monitor_list.test.tsx.snap +++ b/x-pack/plugins/uptime/public/components/overview/monitor_list/__snapshots__/monitor_list.test.tsx.snap @@ -1052,7 +1052,7 @@ exports[`MonitorList component renders the monitor list 1`] = ` scope="col" >
{ @@ -112,6 +114,10 @@ describe('MonitorList component', () => { beforeAll(() => { mockMoment(); + global.innerWidth = 1200; + + // Trigger the window resize event. + global.dispatchEvent(new Event('resize')); }); const getMonitorList = (timestamp?: string): MonitorSummariesResult => { @@ -275,6 +281,67 @@ describe('MonitorList component', () => { }); }); + describe('responsive behavior', () => { + describe('xl screens', () => { + beforeAll(() => { + global.innerWidth = 1200; + + // Trigger the window resize event. + global.dispatchEvent(new Event('resize')); + }); + + it('shows ping histogram and expand button on xl and xxl screens', async () => { + const list = getMonitorList(moment().subtract(5, 'minute').toISOString()); + const { getByTestId, getByText } = render( + + ); + + await waitFor(() => { + expect( + getByTestId( + `xpack.uptime.monitorList.${list.summaries[0].monitor_id}.expandMonitorDetail` + ) + ).toBeInTheDocument(); + expect(getByText('Downtime history')).toBeInTheDocument(); + }); + }); + }); + + describe('large and medium screens', () => { + it('hides ping histogram and expand button on extra large screens', async () => { + global.innerWidth = 1199; + + // Trigger the window resize event. + global.dispatchEvent(new Event('resize')); + + const { queryByTestId, queryByText } = render( + + ); + + await waitFor(() => { + expect( + queryByTestId('xpack.uptime.monitorList.always-down.expandMonitorDetail') + ).not.toBeInTheDocument(); + expect(queryByText('Downtime history')).not.toBeInTheDocument(); + }); + }); + }); + }); + describe('noItemsMessage', () => { it('returns loading message while loading', () => { expect(noItemsMessage(true)).toEqual(`Loading...`); diff --git a/x-pack/plugins/uptime/public/components/overview/monitor_list/monitor_list.tsx b/x-pack/plugins/uptime/public/components/overview/monitor_list/monitor_list.tsx index 0b707588acfb5..37803dff88ce9 100644 --- a/x-pack/plugins/uptime/public/components/overview/monitor_list/monitor_list.tsx +++ b/x-pack/plugins/uptime/public/components/overview/monitor_list/monitor_list.tsx @@ -4,7 +4,9 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ - +import React, { useState } from 'react'; +import useWindowSize from 'react-use/lib/useWindowSize'; +import useDebounce from 'react-use/lib/useDebounce'; import { EuiButtonIcon, EuiBasicTable, @@ -13,8 +15,8 @@ import { EuiLink, EuiPanel, EuiSpacer, + getBreakpoint, } from '@elastic/eui'; -import React, { useState } from 'react'; import { HistogramPoint, X509Expiry } from '../../../../common/runtime_types'; import { MonitorSummary } from '../../../../common/runtime_types'; import { MonitorListStatusColumn } from './columns/monitor_status_column'; @@ -51,15 +53,33 @@ export const MonitorListComponent: ({ pageSize, setPageSize, }: Props) => any = ({ filters, monitorList: { list, error, loading }, pageSize, setPageSize }) => { - const [drawerIds, updateDrawerIds] = useState([]); + const [expandedDrawerIds, updateExpandedDrawerIds] = useState([]); + const { width } = useWindowSize(); + const [hideExtraColumns, setHideExtraColumns] = useState(false); + + useDebounce( + () => { + setHideExtraColumns(['m', 'l'].includes(getBreakpoint(width) ?? '')); + }, + 50, + [width] + ); const items = list.summaries ?? []; const nextPagePagination = list.nextPagePagination ?? ''; const prevPagePagination = list.prevPagePagination ?? ''; + const toggleDrawer = (id: string) => { + if (expandedDrawerIds.includes(id)) { + updateExpandedDrawerIds(expandedDrawerIds.filter((p) => p !== id)); + } else { + updateExpandedDrawerIds([...expandedDrawerIds, id]); + } + }; + const getExpandedRowMap = () => { - return drawerIds.reduce((map: ExpandedRowMap, id: string) => { + return expandedDrawerIds.reduce((map: ExpandedRowMap, id: string) => { return { ...map, [id]: ( @@ -72,104 +92,113 @@ export const MonitorListComponent: ({ }; const columns = [ - { - align: 'left' as const, - field: 'state.summary.status', - name: labels.STATUS_COLUMN_LABEL, - mobileOptions: { - fullWidth: true, + ...[ + { + align: 'left' as const, + field: 'state.summary.status', + name: labels.STATUS_COLUMN_LABEL, + mobileOptions: { + fullWidth: true, + }, + render: (status: string, { state: { timestamp, summaryPings } }: MonitorSummary) => { + return ( + + ); + }, }, - render: (status: string, { state: { timestamp, summaryPings } }: MonitorSummary) => { - return ( - - ); + { + align: 'left' as const, + field: 'state.monitor.name', + name: labels.NAME_COLUMN_LABEL, + mobileOptions: { + fullWidth: true, + }, + render: (_name: string, summary: MonitorSummary) => , + sortable: true, }, - }, - { - align: 'left' as const, - field: 'state.monitor.name', - name: labels.NAME_COLUMN_LABEL, - mobileOptions: { - fullWidth: true, + { + align: 'left' as const, + field: 'state.url.full', + name: URL_LABEL, + width: '30%', + render: (url: string) => ( + + {url} + + ), }, - render: (name: string, summary: MonitorSummary) => , - sortable: true, - }, - { - align: 'left' as const, - field: 'state.url.full', - name: URL_LABEL, - width: '30%', - render: (url: string) => ( - - {url} - - ), - }, - { - align: 'left' as const, - field: 'state.monitor.name', - name: TAGS_LABEL, - width: '12%', - render: (_name: string, summary: MonitorSummary) => , - }, - { - align: 'left' as const, - field: 'state.tls.server.x509', - name: labels.TLS_COLUMN_LABEL, - render: (x509: X509Expiry) => , - }, - { - align: 'center' as const, - field: 'histogram.points', - name: labels.HISTORY_COLUMN_LABEL, - mobileOptions: { - show: false, + { + align: 'left' as const, + field: 'state.monitor.name', + name: TAGS_LABEL, + width: '12%', + render: (_name: string, summary: MonitorSummary) => , }, - render: (histogramSeries: HistogramPoint[] | null, summary: MonitorSummary) => ( - - ), - }, - { - align: 'center' as const, - field: '', - name: STATUS_ALERT_COLUMN, - width: '100px', - render: (item: MonitorSummary) => ( - - ), - }, - { - align: 'right' as const, - field: 'monitor_id', - name: '', - sortable: true, - isExpander: true, - width: '40px', - render: (id: string) => { - return ( - { - if (drawerIds.includes(id)) { - updateDrawerIds(drawerIds.filter((p) => p !== id)); - } else { - updateDrawerIds([...drawerIds, id]); - } - }} + { + align: 'left' as const, + field: 'state.tls.server.x509', + name: labels.TLS_COLUMN_LABEL, + render: (x509: X509Expiry) => , + }, + ], + ...(!hideExtraColumns + ? [ + { + align: 'left' as const, + field: 'histogram.points', + name: labels.HISTORY_COLUMN_LABEL, + mobileOptions: { + show: false, + }, + render: (histogramSeries: HistogramPoint[] | null, summary: MonitorSummary) => ( + + ), + }, + ] + : []), + ...[ + { + align: 'center' as const, + field: '', + name: STATUS_ALERT_COLUMN, + width: '100px', + render: (item: MonitorSummary) => ( + - ); + ), }, - }, + ], + ...(!hideExtraColumns + ? [ + { + align: 'right' as const, + field: 'monitor_id', + name: '', + sortable: true, + isExpander: true, + width: '40px', + render: (id: string) => { + return ( + toggleDrawer(id)} + /> + ); + }, + }, + ] + : []), ]; return ( @@ -188,6 +217,14 @@ export const MonitorListComponent: ({ noItemsMessage={noItemsMessage(loading, filters)} columns={columns} tableLayout={'auto'} + rowProps={ + hideExtraColumns + ? ({ monitor_id: monitorId }) => ({ + onClick: () => toggleDrawer(monitorId), + 'aria-label': labels.getExpandDrawerLabel(monitorId), + }) + : undefined + } /> diff --git a/x-pack/plugins/uptime/public/routes.tsx b/x-pack/plugins/uptime/public/routes.tsx index 2b0cc4dc5e5c2..e19f4bd5f93c1 100644 --- a/x-pack/plugins/uptime/public/routes.tsx +++ b/x-pack/plugins/uptime/public/routes.tsx @@ -6,6 +6,7 @@ */ import React, { FC, useEffect } from 'react'; +import styled from 'styled-components'; import { Route, Switch } from 'react-router-dom'; import { FormattedMessage } from '@kbn/i18n/react'; import { i18n } from '@kbn/i18n'; @@ -144,6 +145,12 @@ export const PageRouter: FC = () => { } = useKibana(); const PageTemplateComponent = observability.navigation.PageTemplate; + const StyledPageTemplateComponent = styled(PageTemplateComponent)` + .euiPageHeaderContent > .euiFlexGroup { + flex-wrap: wrap; + } + `; + return ( {Routes.map( @@ -153,9 +160,9 @@ export const PageRouter: FC = () => { {pageHeader ? ( - + - + ) : ( )}