diff --git a/x-pack/plugins/infra/public/assets/anomaly_chart_minified.svg b/x-pack/plugins/infra/public/assets/anomaly_chart_minified.svg new file mode 100644 index 000000000000..dd1b39248bba --- /dev/null +++ b/x-pack/plugins/infra/public/assets/anomaly_chart_minified.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/x-pack/plugins/infra/public/components/logging/log_analysis_setup/index.ts b/x-pack/plugins/infra/public/components/logging/log_analysis_setup/index.ts index 7f2982f221a3..72099e9b1b4b 100644 --- a/x-pack/plugins/infra/public/components/logging/log_analysis_setup/index.ts +++ b/x-pack/plugins/infra/public/components/logging/log_analysis_setup/index.ts @@ -13,3 +13,4 @@ export * from './missing_results_privileges_prompt'; export * from './missing_setup_privileges_prompt'; export * from './ml_unavailable_prompt'; export * from './setup_status_unknown_prompt'; +export * from './subscription_splash_content'; diff --git a/x-pack/plugins/infra/public/components/logging/log_analysis_setup/subscription_splash_content.tsx b/x-pack/plugins/infra/public/components/logging/log_analysis_setup/subscription_splash_content.tsx new file mode 100644 index 000000000000..e0e293b1cc3e --- /dev/null +++ b/x-pack/plugins/infra/public/components/logging/log_analysis_setup/subscription_splash_content.tsx @@ -0,0 +1,174 @@ +/* + * 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 React, { useEffect } from 'react'; +import { i18n } from '@kbn/i18n'; +import { + EuiPage, + EuiPageBody, + EuiPageContent, + EuiFlexGroup, + EuiFlexItem, + EuiSpacer, + EuiTitle, + EuiText, + EuiButton, + EuiButtonEmpty, + EuiImage, +} from '@elastic/eui'; +import { FormattedMessage } from '@kbn/i18n/react'; +import { LoadingPage } from '../../loading_page'; + +import { useKibana } from '../../../../../../../src/plugins/kibana_react/public'; +import { euiStyled } from '../../../../../observability/public'; +import { useTrialStatus } from '../../../hooks/use_trial_status'; + +export const SubscriptionSplashContent: React.FC = () => { + const { services } = useKibana(); + const { loadState, isTrialAvailable, checkTrialAvailability } = useTrialStatus(); + + useEffect(() => { + checkTrialAvailability(); + }, [checkTrialAvailability]); + + if (loadState === 'pending') { + return ( + + ); + } + + const canStartTrial = isTrialAvailable && loadState === 'resolved'; + + let title; + let description; + let cta; + + if (canStartTrial) { + title = ( + + ); + + description = ( + + ); + + cta = ( + + + + ); + } else { + title = ( + + ); + + description = ( + + ); + + cta = ( + + + + ); + } + + return ( + + + + + + +

{title}

+
+ + +

{description}

+
+ +
{cta}
+
+ + + +
+ + +

+ +

+
+ + + +
+
+
+
+ ); +}; + +const SubscriptionPage = euiStyled(EuiPage)` + height: 100% +`; + +const SubscriptionPageContent = euiStyled(EuiPageContent)` + max-width: 768px !important; +`; + +const SubscriptionPageFooter = euiStyled.div` + background: ${(props) => props.theme.eui.euiColorLightestShade}; + margin: 0 -${(props) => props.theme.eui.paddingSizes.l} -${(props) => + props.theme.eui.paddingSizes.l}; + padding: ${(props) => props.theme.eui.paddingSizes.l}; +`; diff --git a/x-pack/plugins/infra/public/hooks/use_trial_status.tsx b/x-pack/plugins/infra/public/hooks/use_trial_status.tsx new file mode 100644 index 000000000000..9cc118d09c7e --- /dev/null +++ b/x-pack/plugins/infra/public/hooks/use_trial_status.tsx @@ -0,0 +1,51 @@ +/* + * 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 { boolean } from 'io-ts'; +import { i18n } from '@kbn/i18n'; + +import { useState } from 'react'; +import { useKibana } from '../../../../../src/plugins/kibana_react/public'; +import { API_BASE_PATH as LICENSE_MANAGEMENT_API_BASE_PATH } from '../../../license_management/common/constants'; +import { useTrackedPromise } from '../utils/use_tracked_promise'; +import { decodeOrThrow } from '../../common/runtime_types'; + +interface UseTrialStatusState { + loadState: 'uninitialized' | 'pending' | 'resolved' | 'rejected'; + isTrialAvailable: boolean; + checkTrialAvailability: () => void; +} + +export function useTrialStatus(): UseTrialStatusState { + const { services } = useKibana(); + const [isTrialAvailable, setIsTrialAvailable] = useState(false); + + const [loadState, checkTrialAvailability] = useTrackedPromise( + { + createPromise: async () => { + const response = await services.http.get(`${LICENSE_MANAGEMENT_API_BASE_PATH}/start_trial`); + return decodeOrThrow(boolean)(response); + }, + onResolve: (response) => { + setIsTrialAvailable(response); + }, + onReject: (error) => { + services.notifications.toasts.addDanger( + i18n.translate('xpack.infra.trialStatus.trialStatusNetworkErrorMessage', { + defaultMessage: 'We could not determine if the trial license is available', + }) + ); + }, + }, + [services] + ); + + return { + loadState: loadState.state, + isTrialAvailable, + checkTrialAvailability, + }; +} diff --git a/x-pack/plugins/infra/public/pages/logs/log_entry_categories/page_content.tsx b/x-pack/plugins/infra/public/pages/logs/log_entry_categories/page_content.tsx index 04b472ceb59c..5d9adb8a4f6e 100644 --- a/x-pack/plugins/infra/public/pages/logs/log_entry_categories/page_content.tsx +++ b/x-pack/plugins/infra/public/pages/logs/log_entry_categories/page_content.tsx @@ -12,7 +12,7 @@ import { LogAnalysisSetupStatusUnknownPrompt, MissingResultsPrivilegesPrompt, MissingSetupPrivilegesPrompt, - MlUnavailablePrompt, + SubscriptionSplashContent, } from '../../../components/logging/log_analysis_setup'; import { SourceErrorPage } from '../../../components/source_error_page'; import { SourceLoadingPage } from '../../../components/source_loading_page'; @@ -50,7 +50,7 @@ export const LogEntryCategoriesPageContent = () => { } else if (hasFailedLoadingSource) { return ; } else if (!hasLogAnalysisCapabilites) { - return ; + return ; } else if (!hasLogAnalysisReadCapabilities) { return ; } else if (setupStatus.type === 'initializing') { diff --git a/x-pack/plugins/infra/public/pages/logs/log_entry_rate/page_content.tsx b/x-pack/plugins/infra/public/pages/logs/log_entry_rate/page_content.tsx index fc07289f02fe..4ec05a977851 100644 --- a/x-pack/plugins/infra/public/pages/logs/log_entry_rate/page_content.tsx +++ b/x-pack/plugins/infra/public/pages/logs/log_entry_rate/page_content.tsx @@ -12,7 +12,7 @@ import { LogAnalysisSetupStatusUnknownPrompt, MissingResultsPrivilegesPrompt, MissingSetupPrivilegesPrompt, - MlUnavailablePrompt, + SubscriptionSplashContent, } from '../../../components/logging/log_analysis_setup'; import { SourceErrorPage } from '../../../components/source_error_page'; import { SourceLoadingPage } from '../../../components/source_loading_page'; @@ -50,7 +50,7 @@ export const LogEntryRatePageContent = () => { } else if (hasFailedLoadingSource) { return ; } else if (!hasLogAnalysisCapabilites) { - return ; + return ; } else if (!hasLogAnalysisReadCapabilities) { return ; } else if (setupStatus.type === 'initializing') { diff --git a/x-pack/plugins/infra/public/pages/logs/page_content.tsx b/x-pack/plugins/infra/public/pages/logs/page_content.tsx index 78b7f86993cb..c5047dbdf3bb 100644 --- a/x-pack/plugins/infra/public/pages/logs/page_content.tsx +++ b/x-pack/plugins/infra/public/pages/logs/page_content.tsx @@ -17,7 +17,6 @@ import { HelpCenterContent } from '../../components/help_center_content'; import { AppNavigation } from '../../components/navigation/app_navigation'; import { RoutedTabs } from '../../components/navigation/routed_tabs'; import { ColumnarPage } from '../../components/page'; -import { useLogAnalysisCapabilitiesContext } from '../../containers/logs/log_analysis'; import { useLogSourceContext } from '../../containers/logs/log_source'; import { RedirectWithQueryParams } from '../../utils/redirect_with_query_params'; import { LogEntryCategoriesPage } from './log_entry_categories'; @@ -28,7 +27,6 @@ import { AlertDropdown } from '../../components/alerting/logs/alert_dropdown'; export const LogsPageContent: React.FunctionComponent = () => { const uiCapabilities = useKibana().services.application?.capabilities; - const logAnalysisCapabilities = useLogAnalysisCapabilitiesContext(); const { initialize } = useLogSourceContext(); @@ -79,13 +77,7 @@ export const LogsPageContent: React.FunctionComponent = () => { - +