mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 09:19:04 -04:00
# Backport This will backport the following commits from `main` to `8.6`: - [[Uptime] Don't show no data state while loading for ping histogram (#145244)](https://github.com/elastic/kibana/pull/145244) <!--- Backport version: 8.9.7 --> ### Questions ? Please refer to the [Backport tool documentation](https://github.com/sqren/backport) <!--BACKPORT [{"author":{"name":"Shahzad","email":"shahzad.muhammad@elastic.co"},"sourceCommit":{"committedDate":"2022-11-22T19:51:42Z","message":"[Uptime] Don't show no data state while loading for ping histogram (#145244)\n\nFixes https://github.com/elastic/kibana/issues/145243","sha":"c3b96a379a341ad842fb01bd0eab533baa7fcf8f","branchLabelMapping":{"^v8.7.0$":"main","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["Team:uptime","release_note:skip","v8.6.0","v8.7.0"],"number":145244,"url":"https://github.com/elastic/kibana/pull/145244","mergeCommit":{"message":"[Uptime] Don't show no data state while loading for ping histogram (#145244)\n\nFixes https://github.com/elastic/kibana/issues/145243","sha":"c3b96a379a341ad842fb01bd0eab533baa7fcf8f"}},"sourceBranch":"main","suggestedTargetBranches":["8.6"],"targetPullRequestStates":[{"branch":"8.6","label":"v8.6.0","labelRegex":"^v(\\d+).(\\d+).\\d+$","isSourceBranch":false,"state":"NOT_CREATED"},{"branch":"main","label":"v8.7.0","labelRegex":"^v8.7.0$","isSourceBranch":true,"state":"MERGED","url":"https://github.com/elastic/kibana/pull/145244","number":145244,"mergeCommit":{"message":"[Uptime] Don't show no data state while loading for ping histogram (#145244)\n\nFixes https://github.com/elastic/kibana/issues/145243","sha":"c3b96a379a341ad842fb01bd0eab533baa7fcf8f"}}]}] BACKPORT--> Co-authored-by: Shahzad <shahzad.muhammad@elastic.co>
This commit is contained in:
parent
7b99f4c6cd
commit
1e89fbe536
12 changed files with 66 additions and 84 deletions
|
@ -17,24 +17,20 @@ import {
|
|||
ElementClickListener,
|
||||
ScaleType,
|
||||
} from '@elastic/charts';
|
||||
import { EuiTitle, EuiFlexGroup, EuiFlexItem, EuiButton } from '@elastic/eui';
|
||||
import { EuiTitle, EuiFlexGroup, EuiFlexItem } from '@elastic/eui';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import React, { useContext } from 'react';
|
||||
import { FormattedMessage } from '@kbn/i18n-react';
|
||||
import numeral from '@elastic/numeral';
|
||||
import moment from 'moment';
|
||||
import { useSelector } from 'react-redux';
|
||||
import { createExploratoryViewUrl } from '@kbn/observability-plugin/public';
|
||||
import { getChartDateLabel } from '../../../lib/helper';
|
||||
import { ChartWrapper } from './chart_wrapper';
|
||||
import { UptimeThemeContext } from '../../../contexts';
|
||||
import { HistogramResult } from '../../../../../common/runtime_types';
|
||||
import { useMonitorId, useUrlParams } from '../../../hooks';
|
||||
import { useUrlParams } from '../../../hooks';
|
||||
import { ChartEmptyState } from './chart_empty_state';
|
||||
import { getDateRangeFromChartElement } from './utils';
|
||||
import { STATUS_DOWN_LABEL, STATUS_UP_LABEL } from '../translations';
|
||||
import { useUptimeSettingsContext } from '../../../contexts/uptime_settings_context';
|
||||
import { monitorStatusSelector } from '../../../state/selectors';
|
||||
|
||||
export interface PingHistogramComponentProps {
|
||||
/**
|
||||
|
@ -77,18 +73,10 @@ export const PingHistogramComponent: React.FC<PingHistogramComponentProps> = ({
|
|||
chartTheme,
|
||||
} = useContext(UptimeThemeContext);
|
||||
|
||||
const monitorId = useMonitorId();
|
||||
|
||||
const selectedMonitor = useSelector(monitorStatusSelector);
|
||||
|
||||
const { basePath } = useUptimeSettingsContext();
|
||||
|
||||
const [getUrlParams, updateUrlParams] = useUrlParams();
|
||||
|
||||
const { dateRangeStart, dateRangeEnd } = getUrlParams();
|
||||
const [_getUrlParams, updateUrlParams] = useUrlParams();
|
||||
|
||||
let content: JSX.Element | undefined;
|
||||
if (!data?.histogram?.length) {
|
||||
if (!data?.histogram?.length && !loading) {
|
||||
content = (
|
||||
<ChartEmptyState
|
||||
title={i18n.translate('xpack.synthetics.snapshot.noDataTitle', {
|
||||
|
@ -100,7 +88,7 @@ export const PingHistogramComponent: React.FC<PingHistogramComponentProps> = ({
|
|||
/>
|
||||
);
|
||||
} else {
|
||||
const { histogram, minInterval } = data;
|
||||
const { histogram, minInterval } = data ?? {};
|
||||
|
||||
const onBrushEnd: BrushEndListener = ({ x }) => {
|
||||
if (!x) {
|
||||
|
@ -115,13 +103,13 @@ export const PingHistogramComponent: React.FC<PingHistogramComponentProps> = ({
|
|||
|
||||
const onBarClicked: ElementClickListener = ([elementData]) => {
|
||||
updateUrlParams(
|
||||
getDateRangeFromChartElement(elementData as XYChartElementEvent, minInterval)
|
||||
getDateRangeFromChartElement(elementData as XYChartElementEvent, minInterval!)
|
||||
);
|
||||
};
|
||||
|
||||
const barData: BarPoint[] = [];
|
||||
|
||||
histogram.forEach(({ x, upCount, downCount }) => {
|
||||
histogram?.forEach(({ x, upCount, downCount }) => {
|
||||
barData.push(
|
||||
{ x, y: downCount ?? 0, type: STATUS_DOWN_LABEL },
|
||||
{ x, y: upCount ?? 0, type: STATUS_UP_LABEL }
|
||||
|
@ -195,29 +183,6 @@ export const PingHistogramComponent: React.FC<PingHistogramComponentProps> = ({
|
|||
);
|
||||
}
|
||||
|
||||
const pingHistogramExploratoryViewLink = createExploratoryViewUrl(
|
||||
{
|
||||
reportType: 'kpi-over-time',
|
||||
allSeries: [
|
||||
{
|
||||
name: `${monitorId}-pings`,
|
||||
dataType: 'synthetics',
|
||||
selectedMetricField: 'summary.up',
|
||||
time: { from: dateRangeStart, to: dateRangeEnd },
|
||||
reportDefinitions: {
|
||||
'monitor.name':
|
||||
monitorId && selectedMonitor?.monitor?.name
|
||||
? [selectedMonitor.monitor.name]
|
||||
: ['ALL_VALUES'],
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
basePath
|
||||
);
|
||||
|
||||
const showAnalyzeButton = false;
|
||||
|
||||
return (
|
||||
<>
|
||||
<EuiFlexGroup>
|
||||
|
@ -231,16 +196,6 @@ export const PingHistogramComponent: React.FC<PingHistogramComponentProps> = ({
|
|||
</h2>
|
||||
</EuiTitle>
|
||||
</EuiFlexItem>
|
||||
{showAnalyzeButton && (
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiButton size="s" href={pingHistogramExploratoryViewLink}>
|
||||
<FormattedMessage
|
||||
id="xpack.synthetics.pingHistogram.analyze"
|
||||
defaultMessage="Analyze"
|
||||
/>
|
||||
</EuiButton>
|
||||
</EuiFlexItem>
|
||||
)}
|
||||
</EuiFlexGroup>
|
||||
{content}
|
||||
</>
|
||||
|
|
|
@ -29,7 +29,7 @@ const Container: React.FC<Props & ResponsiveWrapperProps> = ({ height }) => {
|
|||
dateRangeStart: dateStart,
|
||||
dateRangeEnd: dateEnd,
|
||||
} = useGetUrlParams();
|
||||
const filterCheck = useOverviewFilterCheck();
|
||||
const { filterCheck, pending } = useOverviewFilterCheck();
|
||||
|
||||
const dispatch = useDispatch();
|
||||
const monitorId = useMonitorId();
|
||||
|
@ -76,7 +76,7 @@ const Container: React.FC<Props & ResponsiveWrapperProps> = ({ height }) => {
|
|||
absoluteStartDate={absoluteDateRangeStart}
|
||||
absoluteEndDate={absoluteDateRangeEnd}
|
||||
height={height}
|
||||
loading={loading}
|
||||
loading={loading || pending}
|
||||
timeZone={timeZone}
|
||||
/>
|
||||
);
|
||||
|
|
|
@ -44,6 +44,7 @@ interface Props extends MonitorListProps {
|
|||
setPageSize: (val: number) => void;
|
||||
monitorList: MonitorList;
|
||||
refreshedMonitorIds: string[];
|
||||
isPending?: boolean;
|
||||
}
|
||||
|
||||
export const MonitorListComponent: ({
|
||||
|
@ -52,12 +53,14 @@ export const MonitorListComponent: ({
|
|||
pageSize,
|
||||
refreshedMonitorIds,
|
||||
setPageSize,
|
||||
isPending,
|
||||
}: Props) => any = ({
|
||||
filters,
|
||||
refreshedMonitorIds = [],
|
||||
monitorList: { list, error, loading },
|
||||
pageSize,
|
||||
setPageSize,
|
||||
isPending,
|
||||
}) => {
|
||||
const [expandedDrawerIds, updateExpandedDrawerIds] = useState<string[]>([]);
|
||||
const currentBreakpoint = useCurrentEuiBreakpoint();
|
||||
|
@ -247,13 +250,15 @@ export const MonitorListComponent: ({
|
|||
<EuiBasicTable
|
||||
aria-label={labels.getDescriptionLabel(items.length)}
|
||||
error={error?.body?.message || error?.message}
|
||||
loading={loading}
|
||||
loading={loading || isPending}
|
||||
isExpandable={true}
|
||||
hasActions={true}
|
||||
itemId="monitor_id"
|
||||
itemIdToExpandedRowMap={getExpandedRowMap()}
|
||||
items={items}
|
||||
noItemsMessage={<NoItemsMessage loading={loading} filters={filters} />}
|
||||
noItemsMessage={
|
||||
<NoItemsMessage loading={Boolean(loading || isPending)} filters={filters} />
|
||||
}
|
||||
columns={columns}
|
||||
tableLayout={'auto'}
|
||||
rowProps={
|
||||
|
|
|
@ -33,7 +33,7 @@ const getPageSizeValue = () => {
|
|||
|
||||
export const MonitorList: React.FC<MonitorListProps> = (props) => {
|
||||
const filters = useSelector(esKuerySelector);
|
||||
const filterCheck = useOverviewFilterCheck();
|
||||
const { filterCheck, pending } = useOverviewFilterCheck();
|
||||
|
||||
const [pageSize, setPageSize] = useState<number>(getPageSizeValue);
|
||||
|
||||
|
@ -101,6 +101,7 @@ export const MonitorList: React.FC<MonitorListProps> = (props) => {
|
|||
pageSize={pageSize}
|
||||
setPageSize={setPageSize}
|
||||
refreshedMonitorIds={refreshedMonitorIds}
|
||||
isPending={pending}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -9,18 +9,25 @@ import React, { useState, useEffect } from 'react';
|
|||
import { FormattedMessage } from '@kbn/i18n-react';
|
||||
import { EuiCallOut, EuiLink, EuiButton, EuiFlexItem, EuiFlexGroup, EuiSpacer } from '@elastic/eui';
|
||||
import { useFetcher } from '@kbn/observability-plugin/public';
|
||||
import { useSelector } from 'react-redux';
|
||||
import { getHasZipUrlMonitors } from '../../../state/api/has_zip_url_monitors';
|
||||
import { getDocLinks } from '../../../../kibana_services';
|
||||
import { monitorListSelector } from '../../../state/selectors';
|
||||
|
||||
export const ZIP_URL_DEPRECATION_SESSION_STORAGE_KEY =
|
||||
'SYNTHETICS_ZIP_URL_DEPRECATION_HAS_BEEN_DISMISSED';
|
||||
|
||||
export const ZipUrlDeprecation = () => {
|
||||
const monitorList = useSelector(monitorListSelector);
|
||||
const noticeHasBeenDismissed =
|
||||
window.sessionStorage.getItem(ZIP_URL_DEPRECATION_SESSION_STORAGE_KEY) === 'true';
|
||||
const { data, loading } = useFetcher(() => {
|
||||
return getHasZipUrlMonitors();
|
||||
}, []);
|
||||
// load it when list is loaded
|
||||
if (!noticeHasBeenDismissed && monitorList.isLoaded) {
|
||||
return getHasZipUrlMonitors();
|
||||
}
|
||||
return undefined;
|
||||
}, [monitorList.isLoaded]);
|
||||
const hasZipUrlMonitors = !loading && data && data.hasZipUrlMonitors;
|
||||
const [shouldShowNotice, setShouldShowNotice] = useState(
|
||||
Boolean(hasZipUrlMonitors && !noticeHasBeenDismissed)
|
||||
|
|
|
@ -45,7 +45,7 @@ describe('useOverviewFilterCheck', () => {
|
|||
} = renderHook(() => useOverviewFilterCheck(), { wrapper: getWrapper() });
|
||||
|
||||
const fn = jest.fn();
|
||||
current(fn);
|
||||
current.filterCheck(fn);
|
||||
expect(fn).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
|
@ -57,7 +57,7 @@ describe('useOverviewFilterCheck', () => {
|
|||
});
|
||||
|
||||
const fn = jest.fn();
|
||||
current(fn);
|
||||
current.filterCheck(fn);
|
||||
expect(fn).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
|
@ -70,7 +70,7 @@ describe('useOverviewFilterCheck', () => {
|
|||
});
|
||||
|
||||
const fn = jest.fn();
|
||||
current(fn);
|
||||
current.filterCheck(fn);
|
||||
expect(fn).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
|
@ -83,7 +83,7 @@ describe('useOverviewFilterCheck', () => {
|
|||
});
|
||||
|
||||
const fn = jest.fn();
|
||||
current(fn);
|
||||
current.filterCheck(fn);
|
||||
expect(fn).not.toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
|
@ -96,7 +96,7 @@ describe('useOverviewFilterCheck', () => {
|
|||
});
|
||||
|
||||
const fn = jest.fn();
|
||||
current(fn);
|
||||
current.filterCheck(fn);
|
||||
expect(fn).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -42,12 +42,15 @@ export function useOverviewFilterCheck() {
|
|||
*/
|
||||
const shouldRun = !!filters || !hasFilters(search);
|
||||
|
||||
return useCallback(
|
||||
(fn: () => void) => {
|
||||
if (shouldRun) {
|
||||
fn();
|
||||
}
|
||||
},
|
||||
[shouldRun]
|
||||
);
|
||||
return {
|
||||
pending: !shouldRun,
|
||||
filterCheck: useCallback(
|
||||
(fn: () => void) => {
|
||||
if (shouldRun) {
|
||||
fn();
|
||||
}
|
||||
},
|
||||
[shouldRun]
|
||||
),
|
||||
};
|
||||
}
|
||||
|
|
|
@ -21,6 +21,7 @@ import type { TestNowResponse } from '../api';
|
|||
|
||||
export interface MonitorList {
|
||||
loading: boolean;
|
||||
isLoaded?: boolean;
|
||||
refreshedMonitorIds?: string[];
|
||||
isUpdating?: string[];
|
||||
list: MonitorSummariesResult;
|
||||
|
@ -34,6 +35,7 @@ export const initialState: MonitorList = {
|
|||
summaries: [],
|
||||
},
|
||||
loading: false,
|
||||
isLoaded: false,
|
||||
refreshedMonitorIds: [],
|
||||
};
|
||||
|
||||
|
@ -54,6 +56,7 @@ export const monitorListReducer = handleActions<MonitorList, Payload>(
|
|||
) => ({
|
||||
...state,
|
||||
loading: false,
|
||||
isLoaded: true,
|
||||
error: undefined,
|
||||
list: { ...action.payload },
|
||||
}),
|
||||
|
@ -64,6 +67,7 @@ export const monitorListReducer = handleActions<MonitorList, Payload>(
|
|||
...state,
|
||||
error: action.payload,
|
||||
loading: false,
|
||||
isLoaded: true,
|
||||
}),
|
||||
[String(setUpdatingMonitorId)]: (state: MonitorList, action: Action<string>) => ({
|
||||
...state,
|
||||
|
|
|
@ -55,6 +55,7 @@ export function createUptimeESClient({
|
|||
}) {
|
||||
return {
|
||||
baseESClient: esClient,
|
||||
heartbeatIndices: '',
|
||||
async search<DocumentSource extends unknown, TParams extends estypes.SearchRequest>(
|
||||
params: TParams,
|
||||
operationName?: string,
|
||||
|
@ -62,11 +63,16 @@ export function createUptimeESClient({
|
|||
): Promise<{ body: ESSearchResponse<DocumentSource, TParams> }> {
|
||||
let res: any;
|
||||
let esError: any;
|
||||
const dynamicSettings = await savedObjectsAdapter.getUptimeDynamicSettings(
|
||||
savedObjectsClient!
|
||||
);
|
||||
|
||||
const esParams = { index: index ?? dynamicSettings!.heartbeatIndices, ...params };
|
||||
if (!this.heartbeatIndices) {
|
||||
const dynamicSettings = await savedObjectsAdapter.getUptimeDynamicSettings(
|
||||
savedObjectsClient!
|
||||
);
|
||||
|
||||
this.heartbeatIndices = dynamicSettings?.heartbeatIndices || '';
|
||||
}
|
||||
|
||||
const esParams = { index: index ?? this.heartbeatIndices, ...params };
|
||||
const startTime = process.hrtime();
|
||||
|
||||
const startTimeNow = Date.now();
|
||||
|
@ -110,11 +116,15 @@ export function createUptimeESClient({
|
|||
let res: any;
|
||||
let esError: any;
|
||||
|
||||
const dynamicSettings = await savedObjectsAdapter.getUptimeDynamicSettings(
|
||||
savedObjectsClient!
|
||||
);
|
||||
if (!this.heartbeatIndices) {
|
||||
const dynamicSettings = await savedObjectsAdapter.getUptimeDynamicSettings(
|
||||
savedObjectsClient!
|
||||
);
|
||||
|
||||
const esParams = { index: dynamicSettings!.heartbeatIndices, ...params };
|
||||
this.heartbeatIndices = dynamicSettings?.heartbeatIndices || '';
|
||||
}
|
||||
|
||||
const esParams = { index: this.heartbeatIndices, ...params };
|
||||
const startTime = process.hrtime();
|
||||
|
||||
try {
|
||||
|
@ -132,7 +142,7 @@ export function createUptimeESClient({
|
|||
throw esError;
|
||||
}
|
||||
|
||||
return { result: res, indices: dynamicSettings.heartbeatIndices };
|
||||
return { result: res, indices: this.heartbeatIndices };
|
||||
},
|
||||
getSavedObjectsClient() {
|
||||
return savedObjectsClient;
|
||||
|
|
|
@ -31234,7 +31234,6 @@
|
|||
"xpack.synthetics.page_header.manageMonitors": "Gestion des moniteurs",
|
||||
"xpack.synthetics.page_header.settingsLink": "Paramètres",
|
||||
"xpack.synthetics.page_header.settingsLink.label": "Accédez à la page de paramètres Uptime",
|
||||
"xpack.synthetics.pingHistogram.analyze": "Analyser",
|
||||
"xpack.synthetics.pingList.checkHistoryTitle": "Historique",
|
||||
"xpack.synthetics.pingList.collapseRow": "Réduire",
|
||||
"xpack.synthetics.pingList.columns.failedStep": "Étape ayant échoué",
|
||||
|
|
|
@ -31210,7 +31210,6 @@
|
|||
"xpack.synthetics.page_header.manageMonitors": "モニター管理",
|
||||
"xpack.synthetics.page_header.settingsLink": "設定",
|
||||
"xpack.synthetics.page_header.settingsLink.label": "アップタイム設定ページに移動",
|
||||
"xpack.synthetics.pingHistogram.analyze": "分析",
|
||||
"xpack.synthetics.pingList.checkHistoryTitle": "履歴",
|
||||
"xpack.synthetics.pingList.collapseRow": "縮小",
|
||||
"xpack.synthetics.pingList.columns.failedStep": "失敗したステップ",
|
||||
|
|
|
@ -31245,7 +31245,6 @@
|
|||
"xpack.synthetics.page_header.manageMonitors": "监测管理",
|
||||
"xpack.synthetics.page_header.settingsLink": "设置",
|
||||
"xpack.synthetics.page_header.settingsLink.label": "导航到 Uptime 设置页面",
|
||||
"xpack.synthetics.pingHistogram.analyze": "分析",
|
||||
"xpack.synthetics.pingList.checkHistoryTitle": "历史记录",
|
||||
"xpack.synthetics.pingList.collapseRow": "折叠",
|
||||
"xpack.synthetics.pingList.columns.failedStep": "失败的步骤",
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue