[Telemetry] Lazy imports to reduce bundle size (#135092)

Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
Alejandro Fernández Haro 2022-06-27 16:18:01 +02:00 committed by GitHub
parent 6428f38991
commit fbff48fd30
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 189 additions and 111 deletions

View file

@ -8,7 +8,7 @@
/**
* The amount of time, in milliseconds, to wait between reports when enabled.
* Currently 24 hours.
* Currently, 24 hours.
*/
export const REPORT_INTERVAL_MS = 86400000;

View file

@ -6,7 +6,7 @@
* Side Public License, v 1.
*/
import SemVer from 'semver/classes/semver';
import type SemVer from 'semver/classes/semver';
import semverParse from 'semver/functions/parse';
import { TelemetrySavedObject } from './types';

View file

@ -1,9 +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
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
export { OptedInNoticeBanner } from './opted_in_notice_banner';

View file

@ -0,0 +1,53 @@
/*
* 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 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
import { mountWithIntl } from '@kbn/test-jest-helpers';
import React from 'react';
import { mockTelemetryConstants, mockTelemetryService } from '../mocks';
import { WelcomeTelemetryNotice } from './welcome_telemetry_notice';
describe('WelcomeTelemetryNotice', () => {
const telemetryConstants = mockTelemetryConstants();
test('it should show the opt-out message', () => {
const telemetryService = mockTelemetryService();
const component = mountWithIntl(
<WelcomeTelemetryNotice
telemetryService={telemetryService}
telemetryConstants={telemetryConstants}
addBasePath={(url) => url}
/>
);
expect(component.exists('[id="telemetry.dataManagementDisableCollectionLink"]')).toBe(true);
});
test('it should show the opt-in message', () => {
const telemetryService = mockTelemetryService({ config: { optIn: false } });
const component = mountWithIntl(
<WelcomeTelemetryNotice
telemetryService={telemetryService}
telemetryConstants={telemetryConstants}
addBasePath={(url) => url}
/>
);
expect(component.exists('[id="telemetry.dataManagementEnableCollectionLink"]')).toBe(true);
});
test('it should not show opt-in/out options if user cannot change the settings', () => {
const telemetryService = mockTelemetryService({ config: { allowChangingOptInStatus: false } });
const component = mountWithIntl(
<WelcomeTelemetryNotice
telemetryService={telemetryService}
telemetryConstants={telemetryConstants}
addBasePath={(url) => url}
/>
);
expect(component.exists('[id="telemetry.dataManagementDisableCollectionLink"]')).toBe(false);
expect(component.exists('[id="telemetry.dataManagementEnableCollectionLink"]')).toBe(false);
});
});

View file

@ -0,0 +1,87 @@
/*
* 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 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
import React from 'react';
import { EuiLink, EuiSpacer, EuiTextColor } from '@elastic/eui';
import { FormattedMessage } from '@kbn/i18n-react';
import type { TelemetryConstants } from '../plugin';
import type { TelemetryService } from '../services';
interface Props {
telemetryService: TelemetryService;
addBasePath: (url: string) => string;
telemetryConstants: TelemetryConstants;
}
export const WelcomeTelemetryNotice: React.FC<Props> = ({
telemetryService,
addBasePath,
telemetryConstants,
}: Props) => {
return (
<>
<EuiTextColor className="euiText--small" color="subdued">
<FormattedMessage
id="telemetry.dataManagementDisclaimerPrivacy"
defaultMessage="To learn about how usage data helps us manage and improve our products and services, see our "
/>
<EuiLink href={telemetryConstants.getPrivacyStatementUrl()} target="_blank" rel="noopener">
<FormattedMessage
id="telemetry.dataManagementDisclaimerPrivacyLink"
defaultMessage="Privacy Statement."
/>
</EuiLink>
{renderTelemetryEnabledOrDisabledText(telemetryService, addBasePath)}
</EuiTextColor>
<EuiSpacer size="xs" />
</>
);
};
function renderTelemetryEnabledOrDisabledText(
telemetryService: TelemetryService,
addBasePath: (url: string) => string
) {
if (!telemetryService.userCanChangeSettings || !telemetryService.getCanChangeOptInStatus()) {
return null;
}
const isOptedIn = telemetryService.getIsOptedIn();
if (isOptedIn) {
return (
<>
<FormattedMessage
id="telemetry.dataManagementDisableCollection"
defaultMessage=" To stop collection, "
/>
<EuiLink href={addBasePath('management/kibana/settings')}>
<FormattedMessage
id="telemetry.dataManagementDisableCollectionLink"
defaultMessage="disable usage data here."
/>
</EuiLink>
</>
);
} else {
return (
<>
<FormattedMessage
id="telemetry.dataManagementEnableCollection"
defaultMessage=" To start collection, "
/>
<EuiLink href={addBasePath('management/kibana/settings')}>
<FormattedMessage
id="telemetry.dataManagementEnableCollectionLink"
defaultMessage="enable usage data here."
/>
</EuiLink>
</>
);
}
}

View file

@ -6,8 +6,6 @@
* Side Public License, v 1.
*/
import { ElasticV3BrowserShipper } from '@kbn/analytics-shippers-elastic-v3-browser';
import type {
Plugin,
CoreStart,
@ -19,20 +17,15 @@ import type {
ApplicationStart,
DocLinksStart,
} from '@kbn/core/public';
import type { ScreenshotModePluginSetup } from '@kbn/screenshot-mode-plugin/public';
import type { HomePublicPluginSetup } from '@kbn/home-plugin/public';
import { ElasticV3BrowserShipper } from '@kbn/analytics-shippers-elastic-v3-browser';
import { TelemetrySender, TelemetryService, TelemetryNotifications } from './services';
import type {
TelemetrySavedObjectAttributes,
TelemetrySavedObject,
} from '../common/telemetry_config/types';
import {
getTelemetryAllowChangingOptInStatus,
getTelemetryOptIn,
getTelemetrySendUsageFrom,
} from '../common/telemetry_config';
import { getNotifyUserAboutOptInDefault } from '../common/telemetry_config/get_telemetry_notify_user_about_optin_default';
import { renderWelcomeTelemetryNotice } from './render_welcome_telemetry_notice';
@ -321,6 +314,9 @@ export class TelemetryPlugin implements Plugin<TelemetryPluginSetup, TelemetryPl
const currentKibanaVersion = this.currentKibanaVersion;
const { getTelemetryAllowChangingOptInStatus, getTelemetryOptIn, getTelemetrySendUsageFrom } =
await import('../common/telemetry_config');
const allowChangingOptInStatus = getTelemetryAllowChangingOptInStatus({
configTelemetryAllowChangingOptInStatus,
telemetrySavedObject,

View file

@ -6,35 +6,20 @@
* Side Public License, v 1.
*/
import { mountWithIntl } from '@kbn/test-jest-helpers';
import { shallowWithIntl } from '@kbn/test-jest-helpers';
import React from 'react';
import { renderWelcomeTelemetryNotice } from './render_welcome_telemetry_notice';
import { mockTelemetryConstants, mockTelemetryService } from './mocks';
describe('renderWelcomeTelemetryNotice', () => {
const telemetryConstants = mockTelemetryConstants();
test('it should show the opt-out message', () => {
test('it should render the WelcomeTelemetryNotice component', () => {
const reactLazySpy = jest.spyOn(React, 'lazy');
const telemetryService = mockTelemetryService();
const component = mountWithIntl(
shallowWithIntl(
renderWelcomeTelemetryNotice(telemetryService, (url) => url, telemetryConstants)
);
expect(component.exists('[id="telemetry.dataManagementDisableCollectionLink"]')).toBe(true);
});
test('it should show the opt-in message', () => {
const telemetryService = mockTelemetryService({ config: { optIn: false } });
const component = mountWithIntl(
renderWelcomeTelemetryNotice(telemetryService, (url) => url, telemetryConstants)
);
expect(component.exists('[id="telemetry.dataManagementEnableCollectionLink"]')).toBe(true);
});
test('it should not show opt-in/out options if user cannot change the settings', () => {
const telemetryService = mockTelemetryService({ config: { allowChangingOptInStatus: false } });
const component = mountWithIntl(
renderWelcomeTelemetryNotice(telemetryService, (url) => url, telemetryConstants)
);
expect(component.exists('[id="telemetry.dataManagementDisableCollectionLink"]')).toBe(false);
expect(component.exists('[id="telemetry.dataManagementEnableCollectionLink"]')).toBe(false);
expect(reactLazySpy).toHaveBeenCalledTimes(1);
});
});

View file

@ -7,8 +7,7 @@
*/
import React from 'react';
import { EuiLink, EuiSpacer, EuiTextColor } from '@elastic/eui';
import { FormattedMessage } from '@kbn/i18n-react';
import { withSuspense } from '@kbn/shared-ux-utility';
import type { TelemetryService } from './services';
import { TelemetryConstants } from './plugin';
@ -17,65 +16,19 @@ export function renderWelcomeTelemetryNotice(
addBasePath: (url: string) => string,
telemetryConstants: TelemetryConstants
) {
const WelcomeTelemetryNoticeLazy = withSuspense(
React.lazy(() =>
import('./components/welcome_telemetry_notice').then(({ WelcomeTelemetryNotice }) => ({
default: WelcomeTelemetryNotice,
}))
)
);
return (
<>
<EuiTextColor className="euiText--small" color="subdued">
<FormattedMessage
id="telemetry.dataManagementDisclaimerPrivacy"
defaultMessage="To learn about how usage data helps us manage and improve our products and services, see our "
/>
<EuiLink href={telemetryConstants.getPrivacyStatementUrl()} target="_blank" rel="noopener">
<FormattedMessage
id="telemetry.dataManagementDisclaimerPrivacyLink"
defaultMessage="Privacy Statement."
/>
</EuiLink>
{renderTelemetryEnabledOrDisabledText(telemetryService, addBasePath)}
</EuiTextColor>
<EuiSpacer size="xs" />
</>
<WelcomeTelemetryNoticeLazy
telemetryService={telemetryService}
telemetryConstants={telemetryConstants}
addBasePath={addBasePath}
/>
);
}
function renderTelemetryEnabledOrDisabledText(
telemetryService: TelemetryService,
addBasePath: (url: string) => string
) {
if (!telemetryService.userCanChangeSettings || !telemetryService.getCanChangeOptInStatus()) {
return null;
}
const isOptedIn = telemetryService.getIsOptedIn();
if (isOptedIn) {
return (
<>
<FormattedMessage
id="telemetry.dataManagementDisableCollection"
defaultMessage=" To stop collection, "
/>
<EuiLink href={addBasePath('management/kibana/settings')}>
<FormattedMessage
id="telemetry.dataManagementDisableCollectionLink"
defaultMessage="disable usage data here."
/>
</EuiLink>
</>
);
} else {
return (
<>
<FormattedMessage
id="telemetry.dataManagementEnableCollection"
defaultMessage=" To start collection, "
/>
<EuiLink href={addBasePath('management/kibana/settings')}>
<FormattedMessage
id="telemetry.dataManagementEnableCollectionLink"
defaultMessage="enable usage data here."
/>
</EuiLink>
</>
);
}
}

View file

@ -7,10 +7,10 @@
*/
import React from 'react';
import { OverlayStart } from '@kbn/core/public';
import type { OverlayStart } from '@kbn/core/public';
import { toMountPoint } from '@kbn/kibana-react-plugin/public';
import { OptInBanner } from '../../components/opt_in_banner';
import { TelemetryConstants } from '../..';
import { withSuspense } from '@kbn/shared-ux-utility';
import type { TelemetryConstants } from '../..';
interface RenderBannerConfig {
overlays: OverlayStart;
@ -19,8 +19,14 @@ interface RenderBannerConfig {
}
export function renderOptInBanner({ setOptIn, overlays, telemetryConstants }: RenderBannerConfig) {
const OptInBannerLazy = withSuspense(
React.lazy(() =>
import('../../components/opt_in_banner').then(({ OptInBanner }) => ({ default: OptInBanner }))
)
);
const mount = toMountPoint(
<OptInBanner onChangeOptInClick={setOptIn} telemetryConstants={telemetryConstants} />
<OptInBannerLazy onChangeOptInClick={setOptIn} telemetryConstants={telemetryConstants} />
);
const bannerId = overlays.banners.add(mount, 10000);

View file

@ -7,10 +7,10 @@
*/
import React from 'react';
import { HttpStart, OverlayStart } from '@kbn/core/public';
import type { HttpStart, OverlayStart } from '@kbn/core/public';
import { toMountPoint } from '@kbn/kibana-react-plugin/public';
import { OptedInNoticeBanner } from '../../components/opted_in_notice_banner';
import { TelemetryConstants } from '../..';
import { withSuspense } from '@kbn/shared-ux-utility';
import type { TelemetryConstants } from '../..';
interface RenderBannerConfig {
http: HttpStart;
@ -24,8 +24,15 @@ export function renderOptedInNoticeBanner({
http,
telemetryConstants,
}: RenderBannerConfig) {
const OptedInNoticeBannerLazy = withSuspense(
React.lazy(() =>
import('../../components/opted_in_notice_banner').then(({ OptedInNoticeBanner }) => ({
default: OptedInNoticeBanner,
}))
)
);
const mount = toMountPoint(
<OptedInNoticeBanner
<OptedInNoticeBannerLazy
onSeenBanner={onSeen}
http={http}
telemetryConstants={telemetryConstants}

View file

@ -9,7 +9,7 @@
import { i18n } from '@kbn/i18n';
import { CoreStart } from '@kbn/core/public';
import { TelemetryPluginConfig } from '../plugin';
import { getTelemetryChannelEndpoint } from '../../common/telemetry_config';
import { getTelemetryChannelEndpoint } from '../../common/telemetry_config/get_telemetry_channel_endpoint';
import type { UnencryptedTelemetryPayload, EncryptedTelemetryPayload } from '../../common/types';
import { PAYLOAD_CONTENT_ENCODING } from '../../common/constants';