diff --git a/x-pack/legacy/plugins/uptime/public/apps/plugin.ts b/x-pack/legacy/plugins/uptime/public/apps/plugin.ts index bc4e30b79cb15..c09fdf116e790 100644 --- a/x-pack/legacy/plugins/uptime/public/apps/plugin.ts +++ b/x-pack/legacy/plugins/uptime/public/apps/plugin.ts @@ -30,14 +30,8 @@ export class Plugin { } public start(start: StartObject): void { - const { - core, - plugins: { - data: { autocomplete }, - }, - } = start; const libs: UMFrontendLibs = { - framework: getKibanaFrameworkAdapter(core, autocomplete), + framework: getKibanaFrameworkAdapter(start.core, start.plugins), }; // @ts-ignore improper type description this.chrome.setRootTemplate(template); diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/kuery_bar/index.tsx b/x-pack/legacy/plugins/uptime/public/components/functional/kuery_bar/index.tsx index 72e88d2824073..731f560d315d6 100644 --- a/x-pack/legacy/plugins/uptime/public/components/functional/kuery_bar/index.tsx +++ b/x-pack/legacy/plugins/uptime/public/components/functional/kuery_bar/index.tsx @@ -4,14 +4,12 @@ * you may not use this file except in compliance with the Elastic License. */ -import React, { useState, useEffect, useContext } from 'react'; +import React, { useState, useEffect } from 'react'; import { uniqueId, startsWith } from 'lodash'; import { EuiCallOut } from '@elastic/eui'; import styled from 'styled-components'; import { FormattedMessage } from '@kbn/i18n/react'; import { Typeahead } from './typeahead'; -import { getIndexPattern } from '../../../lib/adapters/index_pattern'; -import { UptimeSettingsContext } from '../../../contexts'; import { useUrlParams } from '../../../hooks'; import { toStaticIndexPattern } from '../../../lib/helper'; import { @@ -20,6 +18,7 @@ import { esKuery, IIndexPattern, } from '../../../../../../../../src/plugins/data/public'; +import { useIndexPattern } from '../../../hooks'; const Container = styled.div` margin-bottom: 10px; @@ -71,16 +70,18 @@ export function KueryBar({ autocomplete }: Props) { suggestions: [], isLoadingIndexPattern: true, }); - const { basePath } = useContext(UptimeSettingsContext); const [indexPattern, setIndexPattern] = useState(undefined); const [isLoadingIndexPattern, setIsLoadingIndexPattern] = useState(true); const [isLoadingSuggestions, setIsLoadingSuggestions] = useState(false); let currentRequestCheck: string; + useIndexPattern((result: any) => setIndexPattern(toStaticIndexPattern(result))); + useEffect(() => { - getIndexPattern(basePath, (result: any) => setIndexPattern(toStaticIndexPattern(result))); - setIsLoadingIndexPattern(false); - }, [basePath]); + if (indexPattern !== undefined) { + setIsLoadingIndexPattern(false); + } + }, [indexPattern]); const [getUrlParams, updateUrlParams] = useUrlParams(); const { search: kuery } = getUrlParams(); diff --git a/x-pack/legacy/plugins/uptime/public/hooks/index.ts b/x-pack/legacy/plugins/uptime/public/hooks/index.ts index 22de59833b08d..aa7bb0a220357 100644 --- a/x-pack/legacy/plugins/uptime/public/hooks/index.ts +++ b/x-pack/legacy/plugins/uptime/public/hooks/index.ts @@ -5,3 +5,5 @@ */ export { useUrlParams } from './use_url_params'; +export { useIndexPattern } from './use_index_pattern'; +export * from './use_telemetry'; diff --git a/x-pack/legacy/plugins/uptime/public/hooks/use_index_pattern.ts b/x-pack/legacy/plugins/uptime/public/hooks/use_index_pattern.ts new file mode 100644 index 0000000000000..eb9b475a35716 --- /dev/null +++ b/x-pack/legacy/plugins/uptime/public/hooks/use_index_pattern.ts @@ -0,0 +1,20 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { useEffect, Dispatch } from 'react'; +import { useKibana } from '../../../../../../src/plugins/kibana_react/public'; + +export const useIndexPattern = (setIndexPattern: Dispatch) => { + const core = useKibana(); + useEffect(() => { + const fetch = core.services.http?.fetch; + async function getIndexPattern() { + if (!fetch) throw new Error('Http core services are not defined'); + setIndexPattern(await fetch('/api/uptime/index_pattern', { method: 'GET' })); + } + getIndexPattern(); + }, [core.services.http, setIndexPattern]); +}; diff --git a/x-pack/legacy/plugins/uptime/public/hooks/use_telemetry.ts b/x-pack/legacy/plugins/uptime/public/hooks/use_telemetry.ts new file mode 100644 index 0000000000000..15f276174e2cf --- /dev/null +++ b/x-pack/legacy/plugins/uptime/public/hooks/use_telemetry.ts @@ -0,0 +1,41 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { useEffect } from 'react'; +import { HttpHandler } from 'kibana/public'; +import { useKibana } from '../../../../../../src/plugins/kibana_react/public'; + +export enum UptimePage { + Overview = '/api/uptime/logOverview', + Monitor = '/api/uptime/logMonitor', + NotFound = '__not-found__', +} + +const getApiPath = (page?: UptimePage) => { + if (!page) throw new Error('Telemetry logging for this page not yet implemented'); + if (page === '__not-found__') + throw new Error('Telemetry logging for 404 page not yet implemented'); + return page.valueOf(); +}; + +const logPageLoad = async (fetch: HttpHandler, page?: UptimePage) => { + try { + await fetch(getApiPath(page), { + method: 'POST', + }); + } catch (e) { + throw e; + } +}; + +export const useUptimeTelemetry = (page?: UptimePage) => { + const kibana = useKibana(); + const fetch = kibana.services.http?.fetch; + useEffect(() => { + if (!fetch) throw new Error('Core http services are not defined'); + logPageLoad(fetch, page); + }, [fetch, page]); +}; diff --git a/x-pack/legacy/plugins/uptime/public/lib/adapters/framework/new_platform_adapter.tsx b/x-pack/legacy/plugins/uptime/public/lib/adapters/framework/new_platform_adapter.tsx index b7ff3b2aa6264..28179c229013b 100644 --- a/x-pack/legacy/plugins/uptime/public/lib/adapters/framework/new_platform_adapter.tsx +++ b/x-pack/legacy/plugins/uptime/public/lib/adapters/framework/new_platform_adapter.tsx @@ -4,12 +4,12 @@ * you may not use this file except in compliance with the Elastic License. */ -import { ChromeBreadcrumb, CoreStart } from 'src/core/public'; +import { ChromeBreadcrumb, LegacyCoreStart } from 'src/core/public'; import React from 'react'; import ReactDOM from 'react-dom'; import { get } from 'lodash'; -import { AutocompleteProviderRegister } from 'src/plugins/data/public'; import { i18n as i18nFormatter } from '@kbn/i18n'; +import { PluginsStart } from 'ui/new_platform/new_platform'; import { CreateGraphQLClient } from './framework_adapter_types'; import { UptimeApp, UptimeAppProps } from '../../../uptime_app'; import { getIntegratedAppAvailability } from './capabilities_adapter'; @@ -19,13 +19,12 @@ import { DEFAULT_DARK_MODE, DEFAULT_TIMEPICKER_QUICK_RANGES, } from '../../../../common/constants'; -import { getTelemetryMonitorPageLogger, getTelemetryOverviewPageLogger } from '../telemetry'; import { UMFrameworkAdapter, BootstrapUptimeApp } from '../../lib'; import { createApolloClient } from './apollo_client_adapter'; export const getKibanaFrameworkAdapter = ( - core: CoreStart, - autocomplete: Pick + core: LegacyCoreStart, + plugins: PluginsStart ): UMFrameworkAdapter => { const { application: { capabilities }, @@ -44,10 +43,10 @@ export const getKibanaFrameworkAdapter = ( ); const canSave = get(capabilities, 'uptime.save', false); const props: UptimeAppProps = { - autocomplete, basePath: basePath.get(), canSave, client: createApolloClient(`${basePath.get()}/api/uptime/graphql`, 'true'), + core, darkMode: core.uiSettings.get(DEFAULT_DARK_MODE), commonlyUsedRanges: core.uiSettings.get(DEFAULT_TIMEPICKER_QUICK_RANGES), i18n, @@ -55,8 +54,7 @@ export const getKibanaFrameworkAdapter = ( isInfraAvailable: infrastructure, isLogsAvailable: logs, kibanaBreadcrumbs: breadcrumbs, - logMonitorPageLoad: getTelemetryMonitorPageLogger('true', basePath.get()), - logOverviewPageLoad: getTelemetryOverviewPageLogger('true', basePath.get()), + plugins, renderGlobalHelpControls: () => setHelpExtension({ appName: i18nFormatter.translate('xpack.uptime.header.appName', { diff --git a/x-pack/legacy/plugins/uptime/public/lib/adapters/index_pattern/__tests__/get_index_pattern.test.ts b/x-pack/legacy/plugins/uptime/public/lib/adapters/index_pattern/__tests__/get_index_pattern.test.ts deleted file mode 100644 index 6654def2f944b..0000000000000 --- a/x-pack/legacy/plugins/uptime/public/lib/adapters/index_pattern/__tests__/get_index_pattern.test.ts +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import axios, { AxiosRequestConfig } from 'axios'; -import { getIndexPattern } from '../get_index_pattern'; - -describe('getIndexPattern', () => { - let axiosSpy: jest.SpyInstance, [string, (AxiosRequestConfig | undefined)?]>; - beforeEach(() => { - axiosSpy = jest.spyOn(axios, 'get'); - }); - - afterEach(() => { - jest.clearAllMocks(); - }); - - it('returns expected data', async () => { - expect.assertions(3); - axiosSpy.mockReturnValue(new Promise(r => r({ data: { foo: 'bar' } }))); - expect(await getIndexPattern()).toEqual({ foo: 'bar' }); - expect(axiosSpy.mock.calls).toHaveLength(1); - expect(axiosSpy.mock.calls[0]).toEqual(['/api/uptime/index_pattern']); - }); - - it('handles the supplied basePath', async () => { - expect.assertions(2); - await getIndexPattern('foo'); - expect(axiosSpy.mock.calls).toHaveLength(1); - expect(axiosSpy.mock.calls[0]).toEqual(['foo/api/uptime/index_pattern']); - }); - - it('supplies the returned data to the given setter function', async () => { - const mockSetter = jest.fn(); - axiosSpy.mockReturnValue(new Promise(r => r({ data: { foo: 'bar' } }))); - await getIndexPattern(undefined, mockSetter); - expect(mockSetter).toHaveBeenCalled(); - expect(mockSetter).toHaveBeenCalledWith({ foo: 'bar' }); - }); - - it('returns undefined when there is an error fetching', async () => { - expect.assertions(1); - axiosSpy.mockReturnValue( - new Promise((resolve, reject) => reject('Request timeout, server could not be reached')) - ); - expect(await getIndexPattern()).toBeUndefined(); - }); -}); diff --git a/x-pack/legacy/plugins/uptime/public/lib/adapters/index_pattern/get_index_pattern.ts b/x-pack/legacy/plugins/uptime/public/lib/adapters/index_pattern/get_index_pattern.ts deleted file mode 100644 index fd4161b35f7dd..0000000000000 --- a/x-pack/legacy/plugins/uptime/public/lib/adapters/index_pattern/get_index_pattern.ts +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import axios from 'axios'; -import { getApiPath } from '../../helper'; - -/** - * Fetches and returns the uptime index pattern, optionally provides it to - * a given setter function. - * @param basePath - the base path, if any - * @param setter - a callback for use with non-async functions like `useEffect` - */ -export const getIndexPattern = async (basePath?: string, setter?: (data: unknown) => void) => { - try { - const { data } = await axios.get(getApiPath('/api/uptime/index_pattern', basePath)); - if (setter) { - setter(data); - } - return data; - } catch { - return undefined; - } -}; diff --git a/x-pack/legacy/plugins/uptime/public/lib/adapters/index_pattern/index.ts b/x-pack/legacy/plugins/uptime/public/lib/adapters/index_pattern/index.ts deleted file mode 100644 index 1c84a7bc3b727..0000000000000 --- a/x-pack/legacy/plugins/uptime/public/lib/adapters/index_pattern/index.ts +++ /dev/null @@ -1,7 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -export { getIndexPattern } from './get_index_pattern'; diff --git a/x-pack/legacy/plugins/uptime/public/lib/adapters/telemetry/index.ts b/x-pack/legacy/plugins/uptime/public/lib/adapters/telemetry/index.ts deleted file mode 100644 index 08d8d9a5d4069..0000000000000 --- a/x-pack/legacy/plugins/uptime/public/lib/adapters/telemetry/index.ts +++ /dev/null @@ -1,8 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -export { getTelemetryMonitorPageLogger } from './log_monitor'; -export { getTelemetryOverviewPageLogger } from './log_overview'; diff --git a/x-pack/legacy/plugins/uptime/public/lib/adapters/telemetry/log_monitor.ts b/x-pack/legacy/plugins/uptime/public/lib/adapters/telemetry/log_monitor.ts deleted file mode 100644 index 20328497d69a8..0000000000000 --- a/x-pack/legacy/plugins/uptime/public/lib/adapters/telemetry/log_monitor.ts +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import axios from 'axios'; -import { getApiPath } from '../../helper'; - -/** - * Generates a function to log a page load of the monitor page for Kibana telemetry. - * @returns a function that can log page loads - */ -export const getTelemetryMonitorPageLogger = (xsrf: string, basePath?: string) => async () => { - await axios.post(getApiPath('/api/uptime/logMonitor', basePath), undefined, { - headers: { 'kbn-xsrf': xsrf }, - }); -}; diff --git a/x-pack/legacy/plugins/uptime/public/lib/adapters/telemetry/log_overview.ts b/x-pack/legacy/plugins/uptime/public/lib/adapters/telemetry/log_overview.ts deleted file mode 100644 index fd9fd773a18b9..0000000000000 --- a/x-pack/legacy/plugins/uptime/public/lib/adapters/telemetry/log_overview.ts +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import axios from 'axios'; -import { getApiPath } from '../../helper'; - -/** - * Generates a function to log a page load of the overview page for Kibana telemtry. - * @returns a function that can log page loads - */ -export const getTelemetryOverviewPageLogger = (xsrf: string, basePath?: string) => async () => { - await axios.post(getApiPath('/api/uptime/logOverview', basePath), undefined, { - headers: { 'kbn-xsrf': xsrf }, - }); -}; diff --git a/x-pack/legacy/plugins/uptime/public/pages/monitor.tsx b/x-pack/legacy/plugins/uptime/public/pages/monitor.tsx index bfd1fa6522692..6f39f9811d269 100644 --- a/x-pack/legacy/plugins/uptime/public/pages/monitor.tsx +++ b/x-pack/legacy/plugins/uptime/public/pages/monitor.tsx @@ -12,14 +12,13 @@ import { getMonitorPageBreadcrumb } from '../breadcrumbs'; import { MonitorCharts, MonitorPageTitle, PingList } from '../components/functional'; import { UMUpdateBreadcrumbs } from '../lib/lib'; import { UptimeSettingsContext } from '../contexts'; -import { useUrlParams } from '../hooks'; +import { useUptimeTelemetry, useUrlParams, UptimePage } from '../hooks'; import { stringifyUrlParams } from '../lib/helper/stringify_url_params'; import { BaseLocationOptions } from '../components/functional/ping_list'; import { useTrackPageview } from '../../../infra/public'; import { MonitorStatusDetails } from '../components/functional/monitor_status_details'; interface MonitorPageProps { - logMonitorPageLoad: () => void; match: { params: { monitorId: string } }; // this is the query function provided by Apollo's Client API query: ( @@ -28,12 +27,7 @@ interface MonitorPageProps { setBreadcrumbs: UMUpdateBreadcrumbs; } -export const MonitorPage = ({ - logMonitorPageLoad, - query, - setBreadcrumbs, - match, -}: MonitorPageProps) => { +export const MonitorPage = ({ query, setBreadcrumbs, match }: MonitorPageProps) => { // decode 64 base string, it was decoded to make it a valid url, since monitor id can be a url const monitorId = atob(match.params.monitorId); const [pingListPageCount, setPingListPageCount] = useState(10); @@ -77,9 +71,7 @@ export const MonitorPage = ({ monitorId, }; - useEffect(() => { - logMonitorPageLoad(); - }, [logMonitorPageLoad]); + useUptimeTelemetry(UptimePage.Monitor); useTrackPageview({ app: 'uptime', path: 'monitor' }); useTrackPageview({ app: 'uptime', path: 'monitor', delay: 15000 }); diff --git a/x-pack/legacy/plugins/uptime/public/pages/overview.tsx b/x-pack/legacy/plugins/uptime/public/pages/overview.tsx index 8e72f964ed128..34bcfb994cd48 100644 --- a/x-pack/legacy/plugins/uptime/public/pages/overview.tsx +++ b/x-pack/legacy/plugins/uptime/public/pages/overview.tsx @@ -19,10 +19,9 @@ import { } from '../components/functional'; import { UMUpdateBreadcrumbs } from '../lib/lib'; import { UptimeSettingsContext } from '../contexts'; -import { useUrlParams } from '../hooks'; +import { useIndexPattern, useUrlParams, useUptimeTelemetry, UptimePage } from '../hooks'; import { stringifyUrlParams } from '../lib/helper/stringify_url_params'; import { useTrackPageview } from '../../../infra/public'; -import { getIndexPattern } from '../lib/adapters/index_pattern'; import { combineFiltersAndUserSearch, stringifyKueries, toStaticIndexPattern } from '../lib/helper'; import { AutocompleteProviderRegister, esKuery } from '../../../../../../src/plugins/data/public'; @@ -34,7 +33,6 @@ interface OverviewPageProps { pathname: string; search: string; }; - logOverviewPageLoad: () => void; setBreadcrumbs: UMUpdateBreadcrumbs; } @@ -54,12 +52,7 @@ const EuiFlexItemStyled = styled(EuiFlexItem)` } `; -export const OverviewPage = ({ - basePath, - autocomplete, - logOverviewPageLoad, - setBreadcrumbs, -}: Props) => { +export const OverviewPage = ({ basePath, autocomplete, setBreadcrumbs }: Props) => { const { colors, setHeadingText } = useContext(UptimeSettingsContext); const [getUrlParams, updateUrl] = useUrlParams(); const { absoluteDateRangeStart, absoluteDateRangeEnd, ...params } = getUrlParams(); @@ -72,11 +65,11 @@ export const OverviewPage = ({ filters: urlFilters, } = params; const [indexPattern, setIndexPattern] = useState(undefined); + useUptimeTelemetry(UptimePage.Overview); + useIndexPattern(setIndexPattern); useEffect(() => { - getIndexPattern(basePath, setIndexPattern); setBreadcrumbs(getOverviewPageBreadcrumbs()); - logOverviewPageLoad(); if (setHeadingText) { setHeadingText( i18n.translate('xpack.uptime.overviewPage.headerText', { @@ -85,7 +78,7 @@ export const OverviewPage = ({ }) ); } - }, [basePath, logOverviewPageLoad, setBreadcrumbs, setHeadingText]); + }, [basePath, setBreadcrumbs, setHeadingText]); useTrackPageview({ app: 'uptime', path: 'overview' }); useTrackPageview({ app: 'uptime', path: 'overview', delay: 15000 }); diff --git a/x-pack/legacy/plugins/uptime/public/uptime_app.tsx b/x-pack/legacy/plugins/uptime/public/uptime_app.tsx index 6a28e3e1d5090..8584e44953c46 100644 --- a/x-pack/legacy/plugins/uptime/public/uptime_app.tsx +++ b/x-pack/legacy/plugins/uptime/public/uptime_app.tsx @@ -13,8 +13,9 @@ import React, { useEffect, useState } from 'react'; import { ApolloProvider } from 'react-apollo'; import { Provider as ReduxProvider } from 'react-redux'; import { BrowserRouter as Router, Route, RouteComponentProps, Switch } from 'react-router-dom'; -import { I18nStart, ChromeBreadcrumb } from 'src/core/public'; -import { AutocompleteProviderRegister } from 'src/plugins/data/public'; +import { I18nStart, ChromeBreadcrumb, LegacyCoreStart } from 'src/core/public'; +import { PluginsStart } from 'ui/new_platform/new_platform'; +import { KibanaContextProvider } from '../../../../../src/plugins/kibana_react/public'; import { UMGraphQLClient, UMUpdateBreadcrumbs, UMUpdateBadge } from './lib/lib'; import { MonitorPage, OverviewPage, NotFoundPage } from './pages'; import { UptimeRefreshContext, UptimeSettingsContext, UMSettingsContextValues } from './contexts'; @@ -36,15 +37,14 @@ export interface UptimeAppProps { basePath: string; canSave: boolean; client: UMGraphQLClient; + core: LegacyCoreStart; darkMode: boolean; - autocomplete: Pick; i18n: I18nStart; isApmAvailable: boolean; isInfraAvailable: boolean; isLogsAvailable: boolean; kibanaBreadcrumbs: ChromeBreadcrumb[]; - logMonitorPageLoad: () => void; - logOverviewPageLoad: () => void; + plugins: PluginsStart; routerBasename: string; setBreadcrumbs: UMUpdateBreadcrumbs; setBadge: UMUpdateBadge; @@ -54,18 +54,17 @@ export interface UptimeAppProps { const Application = (props: UptimeAppProps) => { const { - autocomplete, basePath, canSave, client, + core, darkMode, commonlyUsedRanges, i18n: i18nCore, isApmAvailable, isInfraAvailable, isLogsAvailable, - logMonitorPageLoad, - logOverviewPageLoad, + plugins, renderGlobalHelpControls, routerBasename, setBreadcrumbs, @@ -152,70 +151,70 @@ const Application = (props: UptimeAppProps) => { return ( - - { - return ( - - - - -
- - - -

{headingText}

-
-
- - - -
- - - ( - - )} - /> - ( - + + { + return ( + + + + +
+ + + +

{headingText}

+
+
+ + - )} - /> - - -
-
-
-
-
- ); - }} - /> -
+ + + + + ( + + )} + /> + ( + + )} + /> + + +
+
+
+
+
+ ); + }} + /> +
+
);