[Logs+] Add timed feedback toast (#167682)

## Summary

Closes https://github.com/elastic/kibana/issues/166968

Adds a toast message asking for (optional) feedback when navigating from
Observability Onboarding > Observability Log Explorer (via the Explore
Logs button) after three minutes. The origin is attached to the history
location state as part of the Locator.

## State machine

A lightweight state machine handles the origin interpreting. We will
very likely have more origins in the future.

![Screenshot 2023-10-02 at 17 33
41](b0f9ba81-b857-4185-a2dd-8049fae43932)

## Reviewer hints

- Start the flow at `/app/observabilityOnboarding/customLogs`, continue
to the last step of the wizard, click the "Explore logs" button to
navigate to the Observability Log Explorer.

- You can alter the `FEEDBACK_DELAY` constant for easier testing.

- **Only** the onboarding origin should trigger the feedback toast.

- Moves the feedback link to Observability shared to avoid cyclic
dependency issues.

## Screenshot

![Screenshot 2023-10-03 at 14 45
21](8c5f0ac0-43a5-44f7-a361-4ea2f66e42b8)

---------

Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
Co-authored-by: Marco Antonio Ghiani <marcoantonio.ghiani01@gmail.com>
This commit is contained in:
Kerry Gallagher 2023-10-05 10:45:11 +01:00 committed by GitHub
parent 48b66d72dc
commit 825ef56da5
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
22 changed files with 325 additions and 20 deletions

View file

@ -6,9 +6,18 @@
* Side Public License, v 1.
*/
import { SerializableRecord } from '@kbn/utility-types';
import { LogExplorerNavigationParams } from './log_explorer';
export type DatasetLocatorParams = LogExplorerNavigationParams;
// Will become a union once we have more origins
export interface ObservabilityLogExplorerLocationState extends SerializableRecord {
origin?: {
id: 'application-log-onboarding';
};
}
export type DatasetLocatorParams = LogExplorerNavigationParams &
ObservabilityLogExplorerLocationState;
// All datasets locator
export const ALL_DATASETS_LOCATOR_ID = 'ALL_DATASETS_LOCATOR';

View file

@ -5,6 +5,7 @@
* 2.0.
*/
export type { ObservabilityLogExplorerLocationState } from '@kbn/deeplinks-observability/locators';
import { AllDatasetsLocator } from './all_datasets';
import { SingleDatasetLocator } from './single_dataset';

View file

@ -20,7 +20,7 @@ export const constructLocatorPath = async (params: LocatorPathCosntructionParams
const { isFilterPinned } = await import('@kbn/es-query');
const {
locatorParams: { filters, query, refreshInterval, timeRange, columns, sort },
locatorParams: { filters, query, refreshInterval, timeRange, columns, sort, origin },
index,
useHash,
} = params;
@ -55,6 +55,8 @@ export const constructLocatorPath = async (params: LocatorPathCosntructionParams
return {
app: 'observability-log-explorer',
path,
state: {},
state: {
...(origin ? { origin } : {}),
},
};
};

View file

@ -5,20 +5,24 @@
* 2.0.
*/
import { AppMountParameters, CoreStart } from '@kbn/core/public';
import { CoreStart } from '@kbn/core/public';
import { KibanaRenderContextProvider } from '@kbn/react-kibana-context-render';
import { Route, Router, Routes } from '@kbn/shared-ux-router';
import React from 'react';
import ReactDOM from 'react-dom';
import { ObservablityLogExplorerMainRoute } from '../routes/main';
import { ObservabilityLogExplorerPluginStart, ObservabilityLogExplorerStartDeps } from '../types';
import {
ObservabilityLogExplorerAppMountParameters,
ObservabilityLogExplorerPluginStart,
ObservabilityLogExplorerStartDeps,
} from '../types';
import { useKibanaContextForPluginProvider } from '../utils/use_kibana';
export const renderObservabilityLogExplorer = (
core: CoreStart,
pluginsStart: ObservabilityLogExplorerStartDeps,
ownPluginStart: ObservabilityLogExplorerPluginStart,
appParams: AppMountParameters
appParams: ObservabilityLogExplorerAppMountParameters
) => {
ReactDOM.render(
<ObservabilityLogExplorerApp
@ -40,7 +44,7 @@ export const renderObservabilityLogExplorer = (
};
export interface ObservabilityLogExplorerAppProps {
appParams: AppMountParameters;
appParams: ObservabilityLogExplorerAppMountParameters;
core: CoreStart;
plugins: ObservabilityLogExplorerStartDeps;
pluginStart: ObservabilityLogExplorerPluginStart;

View file

@ -10,7 +10,6 @@ import deepEqual from 'fast-deep-equal';
import useObservable from 'react-use/lib/useObservable';
import { type BehaviorSubject, distinctUntilChanged, filter, take } from 'rxjs';
import { HeaderMenuPortal } from '@kbn/observability-shared-plugin/public';
import { AppMountParameters } from '@kbn/core-application-browser';
import {
EuiBetaBadge,
EuiButton,
@ -37,12 +36,13 @@ import {
onboardingLinkTitle,
} from '../../common/translations';
import { getRouterLinkProps } from '../utils/get_router_link_props';
import { ObservabilityLogExplorerAppMountParameters } from '../types';
interface LogExplorerTopNavMenuProps {
setHeaderActionMenu: AppMountParameters['setHeaderActionMenu'];
setHeaderActionMenu: ObservabilityLogExplorerAppMountParameters['setHeaderActionMenu'];
services: KibanaReactContextValue<PluginKibanaContextValue>['services'];
state$: BehaviorSubject<LogExplorerStateContainer>;
theme$: AppMountParameters['theme$'];
theme$: ObservabilityLogExplorerAppMountParameters['theme$'];
}
export const LogExplorerTopNavMenu = ({

View file

@ -23,6 +23,7 @@ import { OBSERVABILITY_LOG_EXPLORER_APP_ID } from '../common/constants';
import { logExplorerAppTitle } from '../common/translations';
import { renderObservabilityLogExplorer } from './applications/observability_log_explorer';
import type {
ObservabilityLogExplorerAppMountParameters,
ObservabilityLogExplorerPluginSetup,
ObservabilityLogExplorerPluginStart,
ObservabilityLogExplorerSetupDeps,
@ -56,7 +57,7 @@ export class ObservabilityLogExplorerPlugin
: AppNavLinkStatus.hidden,
searchable: true,
keywords: ['logs', 'log', 'explorer', 'logs explorer'],
mount: async (appMountParams) => {
mount: async (appMountParams: ObservabilityLogExplorerAppMountParameters) => {
const [coreStart, pluginsStart, ownPluginStart] = await core.getStartServices();
return renderObservabilityLogExplorer(

View file

@ -5,16 +5,17 @@
* 2.0.
*/
import { AppMountParameters, CoreStart } from '@kbn/core/public';
import { CoreStart } from '@kbn/core/public';
import React, { useState } from 'react';
import { BehaviorSubject } from 'rxjs';
import { LogExplorerTopNavMenu } from '../../components/log_explorer_top_nav_menu';
import { ObservabilityLogExplorerPageTemplate } from '../../components/page_template';
import { noBreadcrumbs, useBreadcrumbs } from '../../utils/breadcrumbs';
import { useKibanaContextForPlugin } from '../../utils/use_kibana';
import { ObservabilityLogExplorerAppMountParameters } from '../../types';
import { LazyOriginInterpreter } from '../../state_machines/origin_interpreter/src/lazy_component';
export interface ObservablityLogExplorerMainRouteProps {
appParams: AppMountParameters;
appParams: ObservabilityLogExplorerAppMountParameters;
core: CoreStart;
}
@ -38,6 +39,7 @@ export const ObservablityLogExplorerMainRoute = ({
state$={state$}
theme$={theme$}
/>
<LazyOriginInterpreter history={history} toasts={core.notifications.toasts} />
<ObservabilityLogExplorerPageTemplate observabilityShared={observabilityShared}>
<logExplorer.LogExplorer scopedHistory={history} state$={state$} />
</ObservabilityLogExplorerPageTemplate>

View file

@ -0,0 +1,8 @@
/*
* 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.
*/
export { createOriginInterpreterStateMachine } from './origin_interpreter/src/state_machine';

View file

@ -0,0 +1,29 @@
/*
* 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 { isDevMode } from '@kbn/xstate-utils';
import { useInterpret } from '@xstate/react';
import {
createOriginInterpreterStateMachine,
OriginInterpreterStateMachineDependencies,
} from './state_machine';
export const OriginInterpreter: React.FC<OriginInterpreterStateMachineDependencies> = ({
history,
toasts,
}) => {
useInterpret(
() =>
createOriginInterpreterStateMachine({
history,
toasts,
}),
{ devTools: isDevMode() }
);
return null;
};

View file

@ -0,0 +1,9 @@
/*
* 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.
*/
export const FEEDBACK_DELAY_MS = 30000; // 30 seconds
export const FEEDBACK_TOAST_LIFETIME_MS = 60000; // 1 minute

View file

@ -0,0 +1,8 @@
/*
* 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.
*/
export const DEFAULT_CONTEXT = undefined;

View file

@ -0,0 +1,16 @@
/*
* 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 { withSuspense } from '@kbn/shared-ux-utility';
import React from 'react';
export const LazyOriginInterpreter = withSuspense(
React.lazy(async () => ({
default: (await import('./component')).OriginInterpreter,
})),
null
);

View file

@ -0,0 +1,27 @@
/*
* 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 { InvokeCreator } from 'xstate';
import { ObservabilityLogExplorerHistory } from '../../../types';
import { OriginInterpreterContext, OriginInterpreterEvent } from './types';
export const initializeFromLocationState =
({
history,
}: {
history: ObservabilityLogExplorerHistory;
}): InvokeCreator<OriginInterpreterContext, OriginInterpreterEvent> =>
(context, event) =>
(callback) => {
const origin = history.location?.state?.origin;
if (!origin) {
return callback('INITIALIZED_WITH_NO_ORIGIN');
} else if (origin.id === 'application-log-onboarding') {
return callback('INITIALIZED_WITH_ONBOARDING_ORIGIN');
}
};

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; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import { IToasts } from '@kbn/core-notifications-browser';
import { mountReactNode } from '@kbn/core-mount-utils-browser-internal';
import { EuiButton, EuiFlexGroup, EuiFlexItem } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import { LOGS_ONBOARDING_FEEDBACK_LINK } from '@kbn/observability-shared-plugin/common';
import React from 'react';
import { FEEDBACK_TOAST_LIFETIME_MS } from './constants';
export const createRequestFeedbackNotifier = (toasts: IToasts) => () => {
toasts.addInfo(
{
title: i18n.translate('xpack.observabilityLogExplorer.feedbackToast.title', {
defaultMessage: 'Tell us what you think!',
}),
text: mountReactNode(
<>
<p>
{i18n.translate('xpack.observabilityLogExplorer.feedbackToast.text', {
defaultMessage: 'Share with us your onboarding experience and help us improve it.',
})}
</p>
<EuiFlexGroup justifyContent="flexEnd" gutterSize="s">
<EuiFlexItem grow={false}>
<EuiButton
data-test-subj="observabilityLogExplorerFeedbackToastButton"
href={LOGS_ONBOARDING_FEEDBACK_LINK}
size="s"
target="_blank"
color="primary"
>
{i18n.translate('xpack.observabilityLogExplorer.feedbackToast.buttonText', {
defaultMessage: 'Take a quick survey',
})}
</EuiButton>
</EuiFlexItem>
</EuiFlexGroup>
</>
),
iconType: 'editorComment',
},
{
toastLifeTimeMs: FEEDBACK_TOAST_LIFETIME_MS,
}
);
};

View file

@ -0,0 +1,88 @@
/*
* 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 { IToasts } from '@kbn/core-notifications-browser';
import { createMachine, InterpreterFrom } from 'xstate';
import { ObservabilityLogExplorerHistory } from '../../../types';
import { FEEDBACK_DELAY_MS } from './constants';
import { DEFAULT_CONTEXT } from './defaults';
import { initializeFromLocationState } from './location_state_service';
import { createRequestFeedbackNotifier } from './notifications';
import {
OriginInterpreterContext,
OriginInterpreterEvent,
OriginInterpreterTypeState,
} from './types';
export const createPureOriginInterpreterStateMachine = (initialContext: OriginInterpreterContext) =>
/** @xstate-layout N4IgpgJg5mDOIC5QBkD2UCiAPADgG1QCcxCAFQ1AMwEs8wA6AVwDtrWAXagQz2oC9IAYgDaABgC6iUDlSxqnVMykgsiAIwAOAMz0NagEwBWUdoBsWgOxaAnEYA0IAJ7rt9UxesWD+2xf2WAXwCHNExcAmIyCho6ejZ5bl4+NigAMQoAWwBVQjxBCEUGNgA3VABrBlDsfCIScipaIo5E-hT01GzchBLUAGMuBWYxcWHlGTlB5VUEYw1dfQ1RQ30LC0NrbX0HZwQ1CwAWemtDLTV991FTPWWtIJD0aoi66Ma45p5W5jTMnLySCkI9HwA0oRAy9Cq4VqUQasXinA+yS+7U6eG6zFK-UGw1GSBA4wSiimiFm80Wy1W60220QenoxlEjP2J32alEmmsdxAkJqkXqMSaCURKQAIgMuAA1ahgADu+UKb1KFQhDyhfJecPeSVF4qlsvRmIG1EUOIkY1khKUeOmPkM9D8pkMFm0bMpFhpM3Obi0tqdxk0Fi5PKeMIFbyF2q+YvYkulcv+RCBeBBYJVYV5z1hgoRkag0dj+p6WONQwkuOkFsm1sQtvt+kdztOojdHquonoah91h9WkWS1MQdVGdDr3hLSRUAAwop2BQ8KQuMwwHhYPKl4rypUhyH+aOtZ8pzO5wulyuDX0jSay2a8QSq6BphZTNZ6Po1O+jMy++YPScLEdLi0UwDG7Z9jkHdMdw1bNxxSadmFnVB50XZdVwTQFgXYUFCHBYNoV3TUIwPeDEOQ09YHPYsrxGG8KwmEtiQQJ8XzfD9DC-RkfycRB9msdt9kuBYNA0Dxlg0Adgm5bd8Og8McwPABlGN2DAEiuDYEg1yaJUt0gmSszk2CviUgZVJndSl0ISjL1LGjJFvSsGOrBAtC0Q4tFEc5DHE-YPI0XjTA9NRDCdI4rhEvR9HrEKIMefSwzHYVjOUsyEIszT0KTFMcLTOL1QMxLcxMlS1I0qyixs017Loy1GNc9zPMdHy-ICoLDDZehzg0Wx3z4vtbkkvD8oS-cBAgegIHFWAwHYBTlzAXpBnoYoPkmzhjPmxaS0EZAAEkFIAFQwAA5AB9A6AHlTsnAAJABBY6AHEMAU8t8UcolnOE-9fLWZ9NEsAwgtc9ttG6p0fQsQCNFitVMxGoixomqaZrmugtsUZbVqNDb0cGQQslIEU7qO07iYOu6FIwA7Tqp5AMEnA7dou463rvJyH1pETOssQx-u0Lwtm43Yzjtbz1jZGwDg2Ab7j04a90RyBkZjabZs2paVt4NaUjRhb8fJynqdpjB6cZ5mzoAJRey7rdO1I7t25AsmttmPqtTmEG+nm-usAHBba9rOp67trGffz-Nh4cCJgxFlbWrg1b1jHmDiCA6AJomSYwMmSaNmm6YZpmWbd+jPs9s5PFff19jWZsDH2IWdk7MP7UdUx-GbdxTGbKOoIK0b45R9W8ZLNOM8NqmC9NouLdO63Douu2Hadl2MFL2rnMr-8jHZWvjEFxvgcZehTn0fZIr48WYcG6SFcI+SkYTpONbHxgcB1qNdTjLSN2VIb4aK0fkPVWqNX6Y3fp-PM39CwYgvNia81V3plw9ioGsbI1CvnfJ5SwtdTB4OBmoF83k+KmHcCcNyN85Z5UAQ-ccIDE5gNHhAj+ONoExj1PGQgAIspYVTAAkcdC47jWfkw-Wb9WHrXYQWGU1kEF2XNCgxib52RYLZL9PBBDhadncPQEwfF-BXGWKIBYfd4pAPoSI4eyclqQLYcVVKMYyq-x6P-O+tDY5JAYS-Zhqc7FSIcaVSyciSxVUUZvT2KjMGsRwQcJ8Wjm7sUwdYEOlgnxOk5LfeWHjDLCJVowke4iWFQMCeZZxmVMLYVwu4wRnj+DeLESnJgkjdYpSCSQEJ1EN73jQQgFR+h6TnGsL5TQQlz5BWCnMEwEsTGeSipk6hcNam5K8eNXoR4kKPQoO-WATBWCDwgIIXax1dpMzuntAAWjnScLMDqWwusgU6j17mE1OndUgu1ukc16bYQ4ngyHuDDs2ICgVtFrB+syICfse5QxsGY++dSkbrIQnOLZqAdnjzAIIQ2p0JS7QwAAdVOoTcmGARRfPLr098T5T6+T4s6RYWhvIen0J5O0TLgpkPWN3FY8KcmFXqWsjZeA0UYuoOnLFJLs7XVufcx5pAHqm1erRZBESqWdh0EsWu-kiG1zWEFDQJxdAbHaqIYZVxnQSUWdHWSAqkXCtFTgXZ-i4LCpPKhFxcC3HZOWXa5WyLSKOudS0r4JFjwoTPBVeRFLUHTF+UcJ8ZCPAwpBUFPi7kNjnGlm+c1fLfUHPoAG1F2ynXNKgWGpC7qVyCAqcmPhOUBExxWYKwtDqS3BvLW6iNFEo2hMQeEnpcbz4JoBcm4FZC01V0NWoHuYd8F9SCJJZgqAIBwGUI26CA7vnTAALSgp2Duu0KTj0npPVFPNTaWB+ogFuyl0wj7aI0AMwFBxOx8ydG+C9trRptB+LkW9saazOmNf5aZ+CfTMjai+PYngjCdgOJ5bQX6B6Ix1BwuMAHGLuFbPg0+6xTV6EuMyK1UkfVNrta6lFlbu2YecsYAZjciGms8qyVlhhfxRQ7F2KW58Fh+2QwjR+rTTLtMILRz22HtHtRYhyN87gpZMoExY4R4nensR0E6PQz5WTsm+h6Tw7ZvIwuZBSZ8stSM0PzUrKxoDCkp1U9MCW9JnQzuGRgvT2ilhTMNSk8+axOz7CU0I1Z+SfFFNTlrcV9jwGoPZnexA5hiEue0+5kSx9-xgxScJXiWqFkWaWeRgtoi7NLXFXQBz6gjDPq8H7KkAkbDpd0DYfs6wTGdiC4ihpJWJFQPzJwiruwRIMf8rxXyzZmSdmPi+VyfFJawfEoYDrzan7WJi2W+xbSymWQG4Y0wnURvNYg0yiZ-ksHn20LxXsIUSMbpQ8AoVVGRXtoG05zTrmdOaDS9oshL5hkUL9D3KKVD8s2ru5Y1tj2g17OvQNtYcwZ2smy+Qp8WggrOnbCHYCLmNX6CW9eiHgb22YoG2cDqrJWR+Dwf6DQaaTG6GluJNy13nR44LUWzZROXWhq7eRAbiXnNabc7pr7zdDV7cQ+1CbthnyBkXUAA */
createMachine<OriginInterpreterContext, OriginInterpreterEvent, OriginInterpreterTypeState>(
{
context: initialContext,
predictableActionArguments: true,
id: 'OriginInterpreter',
initial: 'uninitialized',
states: {
uninitialized: {
always: 'initializingFromLocationState',
},
initializingFromLocationState: {
invoke: {
src: 'initializeFromLocationState',
},
on: {
INITIALIZED_WITH_NO_ORIGIN: '#done',
INITIALIZED_WITH_ONBOARDING_ORIGIN: '#onboarding',
},
},
onboarding: {
id: 'onboarding',
initial: 'waiting',
states: {
waiting: {
after: {
[FEEDBACK_DELAY_MS]: {
target: '#done',
actions: ['requestFeedback'],
},
},
},
},
},
done: {
id: 'done',
type: 'final',
},
},
},
{
actions: {},
guards: {},
}
);
export interface OriginInterpreterStateMachineDependencies {
initialContext?: OriginInterpreterContext;
history: ObservabilityLogExplorerHistory;
toasts: IToasts;
}
export const createOriginInterpreterStateMachine = ({
initialContext = DEFAULT_CONTEXT,
history,
toasts,
}: OriginInterpreterStateMachineDependencies) =>
createPureOriginInterpreterStateMachine(initialContext).withConfig({
actions: {
requestFeedback: createRequestFeedbackNotifier(toasts),
},
services: {
initializeFromLocationState: initializeFromLocationState({ history }),
},
});
export type OriginInterpreterService = InterpreterFrom<typeof createOriginInterpreterStateMachine>;

View file

@ -0,0 +1,32 @@
/*
* 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.
*/
export type OriginInterpreterContext = OriginInterpreterTypeState['context'];
type DefaultOriginInterpreterContext = undefined;
export type OriginInterpreterEvent =
| {
type: 'INITIALIZED_WITH_NO_ORIGIN';
}
| {
type: 'INITIALIZED_WITH_ONBOARDING_ORIGIN';
};
export type OriginInterpreterTypeState =
| {
value: 'uninitialized';
context: DefaultOriginInterpreterContext;
}
| {
value: 'onboarding';
context: DefaultOriginInterpreterContext;
}
| {
value: 'done';
context: DefaultOriginInterpreterContext;
};

View file

@ -11,7 +11,11 @@ import { DiscoverStart } from '@kbn/discover-plugin/public';
import { ObservabilitySharedPluginStart } from '@kbn/observability-shared-plugin/public';
import { ServerlessPluginStart } from '@kbn/serverless/public';
import { SharePluginSetup, SharePluginStart } from '@kbn/share-plugin/public';
import { ObservabilityLogExplorerLocators } from '../common/locators';
import { AppMountParameters, ScopedHistory } from '@kbn/core/public';
import {
ObservabilityLogExplorerLocators,
ObservabilityLogExplorerLocationState,
} from '../common/locators';
export interface ObservabilityLogExplorerPluginSetup {
locators: ObservabilityLogExplorerLocators;
@ -33,3 +37,7 @@ export interface ObservabilityLogExplorerStartDeps {
serverless?: ServerlessPluginStart;
share: SharePluginStart;
}
export type ObservabilityLogExplorerHistory = ScopedHistory<ObservabilityLogExplorerLocationState>;
export type ObservabilityLogExplorerAppMountParameters =
AppMountParameters<ObservabilityLogExplorerLocationState>;

View file

@ -23,13 +23,16 @@
"@kbn/core-chrome-browser",
"@kbn/config-schema",
"@kbn/kibana-utils-plugin",
"@kbn/core-application-browser",
"@kbn/discover-plugin",
"@kbn/es-query",
"@kbn/react-kibana-mount",
"@kbn/share-plugin",
"@kbn/io-ts-utils",
"@kbn/deeplinks-observability"
"@kbn/deeplinks-observability",
"@kbn/core-notifications-browser",
"@kbn/core-mount-utils-browser-internal",
"@kbn/xstate-utils",
"@kbn/shared-ux-utility"
],
"exclude": [
"target/**/*"

View file

@ -72,6 +72,7 @@ export function InstallElasticAgent() {
await singleDatasetLocator!.navigate({
integration,
dataset: enforcedDatasetName,
origin: { id: 'application-log-onboarding' },
});
}

View file

@ -7,11 +7,10 @@
import { EuiButton } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import { LOGS_ONBOARDING_FEEDBACK_LINK } from '@kbn/observability-shared-plugin/common';
import React from 'react';
import { useLocation } from 'react-router-dom';
const LOGS_ONBOARDING_FEEDBACK_LINK = 'https://ela.st/logs-onboarding-feedback';
export function ObservabilityOnboardingHeaderActionMenu() {
const location = useLocation();
const normalizedPathname = location.pathname.replace(/\/$/, '');

View file

@ -84,13 +84,16 @@ export function InstallElasticAgent() {
async function onContinue() {
if (systemIntegrationStatus === 'rejected') {
await allDataSetsLocator!.navigate({});
await allDataSetsLocator!.navigate({
origin: { id: 'application-log-onboarding' },
});
return;
}
await singleDatasetLocator!.navigate({
integration: 'system',
dataset: 'system.syslog',
origin: { id: 'application-log-onboarding' },
});
}

View file

@ -137,3 +137,5 @@ export {
export { ObservabilityTriggerId } from './trigger_ids';
export { getInspectResponse } from './utils/get_inspect_response';
export const LOGS_ONBOARDING_FEEDBACK_LINK = 'https://ela.st/logs-onboarding-feedback';