mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 01:38:56 -04:00
[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.  ## 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  --------- 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:
parent
48b66d72dc
commit
825ef56da5
22 changed files with 325 additions and 20 deletions
|
@ -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';
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
export type { ObservabilityLogExplorerLocationState } from '@kbn/deeplinks-observability/locators';
|
||||
import { AllDatasetsLocator } from './all_datasets';
|
||||
import { SingleDatasetLocator } from './single_dataset';
|
||||
|
||||
|
|
|
@ -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 } : {}),
|
||||
},
|
||||
};
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 = ({
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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';
|
|
@ -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;
|
||||
};
|
|
@ -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
|
|
@ -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;
|
|
@ -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
|
||||
);
|
|
@ -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');
|
||||
}
|
||||
};
|
|
@ -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,
|
||||
}
|
||||
);
|
||||
};
|
|
@ -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>;
|
|
@ -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;
|
||||
};
|
|
@ -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>;
|
||||
|
|
|
@ -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/**/*"
|
||||
|
|
|
@ -72,6 +72,7 @@ export function InstallElasticAgent() {
|
|||
await singleDatasetLocator!.navigate({
|
||||
integration,
|
||||
dataset: enforcedDatasetName,
|
||||
origin: { id: 'application-log-onboarding' },
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -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(/\/$/, '');
|
||||
|
|
|
@ -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' },
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -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';
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue