kibana/x-pack/plugins/observability/public/context/has_data_context.tsx
Shahzad 303806de65
[Exploratory View] Mobile experience (#99565)
Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
Co-authored-by: Bryce Buchanan <bryce.buchanan@elastic.co>
Co-authored-by: Alexander Wert <alexander.wert@elastic.co>
2021-06-18 17:30:53 +02:00

166 lines
5.1 KiB
TypeScript

/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import { uniqueId } from 'lodash';
import React, { createContext, useEffect, useState } from 'react';
import { useRouteMatch } from 'react-router-dom';
import { Alert } from '../../../alerting/common';
import { getDataHandler } from '../data_handler';
import { FETCH_STATUS } from '../hooks/use_fetcher';
import { usePluginContext } from '../hooks/use_plugin_context';
import { useTimeRange } from '../hooks/use_time_range';
import { getObservabilityAlerts } from '../services/get_observability_alerts';
import { ObservabilityFetchDataPlugins } from '../typings/fetch_overview_data';
import { ApmIndicesConfig } from '../../common/typings';
type DataContextApps = ObservabilityFetchDataPlugins | 'alert';
export type HasDataMap = Record<
DataContextApps,
{
status: FETCH_STATUS;
hasData?: boolean | Alert[];
indices?: string | ApmIndicesConfig;
serviceName?: string;
}
>;
export interface HasDataContextValue {
hasDataMap: Partial<HasDataMap>;
hasAnyData: boolean;
isAllRequestsComplete: boolean;
onRefreshTimeRange: () => void;
forceUpdate: string;
}
export const HasDataContext = createContext({} as HasDataContextValue);
const apps: DataContextApps[] = ['apm', 'synthetics', 'infra_logs', 'infra_metrics', 'ux', 'alert'];
export function HasDataContextProvider({ children }: { children: React.ReactNode }) {
const { core } = usePluginContext();
const [forceUpdate, setForceUpdate] = useState('');
const { absoluteStart, absoluteEnd } = useTimeRange();
const [hasDataMap, setHasDataMap] = useState<HasDataContextValue['hasDataMap']>({});
const isExploratoryView = useRouteMatch('/exploratory-view');
useEffect(
() => {
if (!isExploratoryView)
apps.forEach(async (app) => {
try {
const updateState = ({
hasData,
indices,
serviceName,
}: {
hasData?: boolean;
serviceName?: string;
indices?: string | ApmIndicesConfig;
}) => {
setHasDataMap((prevState) => ({
...prevState,
[app]: {
hasData,
...(serviceName ? { serviceName } : {}),
...(indices ? { indices } : {}),
status: FETCH_STATUS.SUCCESS,
},
}));
};
switch (app) {
case 'ux':
const params = { absoluteTime: { start: absoluteStart, end: absoluteEnd } };
const resultUx = await getDataHandler(app)?.hasData(params);
updateState({
hasData: resultUx?.hasData,
indices: resultUx?.indices,
serviceName: resultUx?.serviceName as string,
});
break;
case 'synthetics':
const resultSy = await getDataHandler(app)?.hasData();
updateState({ hasData: resultSy?.hasData, indices: resultSy?.indices });
break;
case 'apm':
const resultApm = await getDataHandler(app)?.hasData();
updateState({ hasData: resultApm?.hasData, indices: resultApm?.indices });
break;
case 'infra_logs':
case 'infra_metrics':
const resultInfra = await getDataHandler(app)?.hasData();
updateState({ hasData: resultInfra });
break;
}
} catch (e) {
setHasDataMap((prevState) => ({
...prevState,
[app]: {
hasData: undefined,
status: FETCH_STATUS.FAILURE,
},
}));
}
});
},
// eslint-disable-next-line react-hooks/exhaustive-deps
[isExploratoryView]
);
useEffect(() => {
async function fetchAlerts() {
try {
const alerts = await getObservabilityAlerts({ core });
setHasDataMap((prevState) => ({
...prevState,
alert: {
hasData: alerts,
status: FETCH_STATUS.SUCCESS,
},
}));
} catch (e) {
setHasDataMap((prevState) => ({
...prevState,
alert: {
hasData: undefined,
status: FETCH_STATUS.FAILURE,
},
}));
}
}
fetchAlerts();
}, [forceUpdate, core]);
const isAllRequestsComplete = apps.every((app) => {
const appStatus = hasDataMap[app]?.status;
return appStatus !== undefined && appStatus !== FETCH_STATUS.LOADING;
});
const hasAnyData = (Object.keys(hasDataMap) as ObservabilityFetchDataPlugins[]).some(
(app) => hasDataMap[app]?.hasData === true
);
return (
<HasDataContext.Provider
value={{
hasDataMap,
hasAnyData,
isAllRequestsComplete,
forceUpdate,
onRefreshTimeRange: () => {
setForceUpdate(uniqueId());
},
}}
children={children}
/>
);
}