[Profiling] adding invalid license page (#154866)

This commit is contained in:
Cauê Marcondes 2023-04-13 17:16:12 -04:00 committed by GitHub
parent b1a4e8c735
commit a061f1d7b3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 128 additions and 12 deletions

View file

@ -23,6 +23,7 @@ import { Services } from './services';
import { ProfilingPluginPublicSetupDeps, ProfilingPluginPublicStartDeps } from './types';
import { ProfilingHeaderActionMenu } from './components/profiling_header_action_menu';
import { RouterErrorBoundary } from './routing/router_error_boundary';
import { LicenseProvider } from './components/contexts/license/license_context';
interface Props {
profilingFetchServices: Services;
@ -86,17 +87,21 @@ function App({
<RouterErrorBoundary>
<TimeRangeContextProvider>
<ProfilingDependenciesContextProvider value={profilingDependencies}>
<CheckSetup>
<RedirectWithDefaultDateRange>
<RouteBreadcrumbsContextProvider>
<RouteRenderer />
</RouteBreadcrumbsContextProvider>
</RedirectWithDefaultDateRange>
</CheckSetup>
<MountProfilingActionMenu
setHeaderActionMenu={setHeaderActionMenu}
theme$={theme$}
/>
<LicenseProvider>
<>
<CheckSetup>
<RedirectWithDefaultDateRange>
<RouteBreadcrumbsContextProvider>
<RouteRenderer />
</RouteBreadcrumbsContextProvider>
</RedirectWithDefaultDateRange>
</CheckSetup>
<MountProfilingActionMenu
setHeaderActionMenu={setHeaderActionMenu}
theme$={theme$}
/>
</>
</LicenseProvider>
</ProfilingDependenciesContextProvider>
</TimeRangeContextProvider>
</RouterErrorBoundary>

View file

@ -19,15 +19,18 @@ import { FormattedMessage } from '@kbn/i18n-react';
import React, { useState } from 'react';
import { AsyncStatus, useAsync } from '../hooks/use_async';
import { useAutoAbortedHttpClient } from '../hooks/use_auto_aborted_http_client';
import { useLicenseContext } from './contexts/license/use_license_context';
import { useProfilingDependencies } from './contexts/profiling_dependencies/use_profiling_dependencies';
import { NoDataPage } from './no_data_page';
import { ProfilingAppPageTemplate } from './profiling_app_page_template';
import { LicensePrompt } from './shared/license_prompt';
export function CheckSetup({ children }: { children: React.ReactElement }) {
const {
start: { core },
services: { fetchHasSetup, postSetupResources },
} = useProfilingDependencies();
const license = useLicenseContext();
const { docLinks, notifications } = core;
@ -42,6 +45,14 @@ export function CheckSetup({ children }: { children: React.ReactElement }) {
const http = useAutoAbortedHttpClient([]);
if (!license?.hasAtLeast('enterprise')) {
return (
<ProfilingAppPageTemplate hideSearchBar tabs={[]}>
<LicensePrompt />
</ProfilingAppPageTemplate>
);
}
const displaySetupScreen =
(status === AsyncStatus.Settled && data?.has_setup !== true) || !!error;

View file

@ -0,0 +1,34 @@
/*
* 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 { ILicense } from '@kbn/licensing-plugin/public';
import React from 'react';
import useObservable from 'react-use/lib/useObservable';
import { ProfilingAppPageTemplate } from '../../profiling_app_page_template';
import { LicensePrompt } from '../../shared/license_prompt';
import { useProfilingDependencies } from '../profiling_dependencies/use_profiling_dependencies';
export const LicenseContext = React.createContext<ILicense | undefined>(undefined);
export function LicenseProvider({ children }: { children: React.ReactChild }) {
const { license$ } = useProfilingDependencies().setup.licensing;
const license = useObservable(license$);
// if license is not loaded yet, consider it valid
const hasInvalidLicense = license?.isActive === false;
// if license is invalid show an error message
if (hasInvalidLicense) {
return (
<ProfilingAppPageTemplate hideSearchBar tabs={[]}>
<LicensePrompt />
</ProfilingAppPageTemplate>
);
}
// render rest of application and pass down license via context
return <LicenseContext.Provider value={license} children={children} />;
}

View file

@ -0,0 +1,13 @@
/*
* 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 { useContext } from 'react';
import { LicenseContext } from './license_context';
export function useLicenseContext() {
return useContext(LicenseContext);
}

View file

@ -0,0 +1,49 @@
/*
* 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 { EuiButton, EuiEmptyPrompt } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import React from 'react';
import url from 'url';
import { useProfilingDependencies } from '../../contexts/profiling_dependencies/use_profiling_dependencies';
const KIBANA_LICENSE_MANAGEMENT_URL = '/app/management/stack/license_management';
export function LicensePrompt() {
const { core } = useProfilingDependencies().start;
const manageLicenseURL = url.format({
pathname: core.http.basePath.prepend(KIBANA_LICENSE_MANAGEMENT_URL),
});
return (
<EuiEmptyPrompt
iconType="logoObservability"
iconColor="warning"
title={
<h1>
{i18n.translate('xpack.profiling.invalidLicense.message', {
defaultMessage: 'To access Universal Profiling, upgrade to an Enterprise subscription',
})}
</h1>
}
body={
<p>
{i18n.translate('xpack.profiling.invalidLicense.description', {
defaultMessage:
'You must have an Enterprise subscription to use Universal Profiling features.',
})}
</p>
}
actions={[
<EuiButton href={manageLicenseURL} fill>
{i18n.translate('xpack.profiling.invalidLicense.subscriptionManagementLink', {
defaultMessage: 'Upgrade subscription',
})}
</EuiButton>,
]}
/>
);
}

View file

@ -14,12 +14,14 @@ import type {
ObservabilityPublicStart,
} from '@kbn/observability-plugin/public';
import { ChartsPluginSetup, ChartsPluginStart } from '@kbn/charts-plugin/public';
import { LicensingPluginSetup } from '@kbn/licensing-plugin/public';
export interface ProfilingPluginPublicSetupDeps {
observability: ObservabilityPublicSetup;
dataViews: DataViewsPublicPluginSetup;
data: DataPublicPluginSetup;
charts: ChartsPluginSetup;
licensing: LicensingPluginSetup;
}
export interface ProfilingPluginPublicStartDeps {