[Logs Explorer] Rename logsExplorer instances in the observability_logs_explorer plugin (#176213)

Renames logsExplorer instances in the `observability_logs_explorer`
plugin.

Related to https://github.com/elastic/kibana/issues/171991
This commit is contained in:
Giorgos Bamparopoulos 2024-02-05 13:18:43 +00:00 committed by GitHub
parent 3b88a0c1eb
commit bceeea80ee
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
36 changed files with 253 additions and 248 deletions

View file

@ -693,7 +693,7 @@ Elastic.
|{kib-repo}blob/{branch}/x-pack/plugins/observability_solution/observability_logs_explorer/README.md[observabilityLogsExplorer]
|This plugin provides an app based on the LogExplorer component from the logs_explorer plugin, but adds observability-specific affordances.
|This plugin provides an app based on the LogsExplorer component from the logs_explorer plugin, but adds observability-specific affordances.
|{kib-repo}blob/{branch}/x-pack/plugins/observability_onboarding/README.md[observabilityOnboarding]

View file

@ -20,18 +20,18 @@ While not fully realized yet, the dependency graph would roughly resemble the fo
```mermaid
flowchart TD
obs_log_explorer_app(Observability Logs Explorer app)
obs_logs_explorer_app(Observability Logs Explorer app)
obs_apps(Other Observability apps)
obs_log_explorer_component(Observability Logs Explorer component)
obs_logs_explorer_component(Observability Logs Explorer component)
other_apps(Other non-Observability apps)
logs_explorer_component(Logs Explorer component)
platform(Kibana Platform)
discover(Discover Main container)
fleet(Fleet / EPM)
obs_log_explorer_app --> obs_log_explorer_component
obs_apps --> obs_log_explorer_component
obs_log_explorer_component --> logs_explorer_component
obs_logs_explorer_app --> obs_logs_explorer_component
obs_apps --> obs_logs_explorer_component
obs_logs_explorer_component --> logs_explorer_component
other_apps --> logs_explorer_component
logs_explorer_component --> discover
logs_explorer_component --> platform

View file

@ -1,6 +1,6 @@
# Observability Logs Explorer
This plugin provides an app based on the `LogExplorer` component from the `logs_explorer` plugin, but adds observability-specific affordances.
This plugin provides an app based on the `LogsExplorer` component from the `logs_explorer` plugin, but adds observability-specific affordances.
## Testing

View file

@ -5,7 +5,7 @@
* 2.0.
*/
export interface ObservabilityLogExplorerConfig {
export interface ObservabilityLogsExplorerConfig {
navigation: {
showAppLink: boolean;
};

View file

@ -7,7 +7,7 @@
import { i18n } from '@kbn/i18n';
export const logExplorerAppTitle = i18n.translate('xpack.observabilityLogsExplorer.appTitle', {
export const logsExplorerAppTitle = i18n.translate('xpack.observabilityLogsExplorer.appTitle', {
defaultMessage: 'Logs Explorer',
});

View file

@ -10,23 +10,23 @@ 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 { DatasetQualityRoute, ObservabilityLogExplorerMainRoute } from '../routes/main';
import { DatasetQualityRoute, ObservabilityLogsExplorerMainRoute } from '../routes/main';
import {
ObservabilityLogExplorerAppMountParameters,
ObservabilityLogExplorerPluginStart,
ObservabilityLogExplorerStartDeps,
ObservabilityLogsExplorerAppMountParameters,
ObservabilityLogsExplorerPluginStart,
ObservabilityLogsExplorerStartDeps,
} from '../types';
import { KbnUrlStateStorageFromRouterProvider } from '../utils/kbn_url_state_context';
import { useKibanaContextForPluginProvider } from '../utils/use_kibana';
export const renderObservabilityLogExplorer = (
export const renderObservabilityLogsExplorer = (
core: CoreStart,
pluginsStart: ObservabilityLogExplorerStartDeps,
ownPluginStart: ObservabilityLogExplorerPluginStart,
appParams: ObservabilityLogExplorerAppMountParameters
pluginsStart: ObservabilityLogsExplorerStartDeps,
ownPluginStart: ObservabilityLogsExplorerPluginStart,
appParams: ObservabilityLogsExplorerAppMountParameters
) => {
ReactDOM.render(
<ObservabilityLogExplorerApp
<ObservabilityLogsExplorerApp
appParams={appParams}
core={core}
plugins={pluginsStart}
@ -44,19 +44,19 @@ export const renderObservabilityLogExplorer = (
};
};
export interface ObservabilityLogExplorerAppProps {
appParams: ObservabilityLogExplorerAppMountParameters;
export interface ObservabilityLogsExplorerAppProps {
appParams: ObservabilityLogsExplorerAppMountParameters;
core: CoreStart;
plugins: ObservabilityLogExplorerStartDeps;
pluginStart: ObservabilityLogExplorerPluginStart;
plugins: ObservabilityLogsExplorerStartDeps;
pluginStart: ObservabilityLogsExplorerPluginStart;
}
export const ObservabilityLogExplorerApp = ({
export const ObservabilityLogsExplorerApp = ({
appParams,
core,
plugins,
pluginStart,
}: ObservabilityLogExplorerAppProps) => {
}: ObservabilityLogsExplorerAppProps) => {
const KibanaContextProviderForPlugin = useKibanaContextForPluginProvider(
core,
plugins,
@ -70,7 +70,7 @@ export const ObservabilityLogExplorerApp = ({
<KbnUrlStateStorageFromRouterProvider>
<Router history={appParams.history}>
<Routes>
<Route path="/" exact={true} render={() => <ObservabilityLogExplorerMainRoute />} />
<Route path="/" exact={true} render={() => <ObservabilityLogsExplorerMainRoute />} />
<Route path="/dataset-quality" exact={true} render={() => <DatasetQualityRoute />} />
</Routes>
</Router>

View file

@ -12,13 +12,13 @@ import { Router } from '@kbn/shared-ux-router';
import { OBSERVABILITY_LOGS_EXPLORER_APP_ID } from '@kbn/deeplinks-observability';
import { AppMountParameters, CoreStart } from '@kbn/core/public';
export const renderObservabilityLogExplorerRedirect = (
export const renderObservabilityLogsExplorerRedirect = (
core: CoreStart,
appParams: AppMountParameters
) => {
ReactDOM.render(
<Router history={appParams.history}>
<ObservabilityLogExplorerRedirect core={core} />
<ObservabilityLogsExplorerRedirect core={core} />
</Router>,
appParams.element
);
@ -28,7 +28,7 @@ export const renderObservabilityLogExplorerRedirect = (
};
};
export const ObservabilityLogExplorerRedirect = ({ core }: { core: CoreStart }) => {
export const ObservabilityLogsExplorerRedirect = ({ core }: { core: CoreStart }) => {
const location = useLocation();
const path = `${location.pathname}${location.search}`;
core.application.navigateToApp(OBSERVABILITY_LOGS_EXPLORER_APP_ID, { replace: true, path });

View file

@ -19,9 +19,9 @@ import { useActor } from '@xstate/react';
import React, { useMemo } from 'react';
import { discoverLinkTitle } from '../../common/translations';
import {
ObservabilityLogExplorerService,
useObservabilityLogExplorerPageStateContext,
} from '../state_machines/observability_log_explorer/src';
ObservabilityLogsExplorerService,
useObservabilityLogsExplorerPageStateContext,
} from '../state_machines/observability_logs_explorer/src';
import { useKibanaContextForPlugin } from '../utils/use_kibana';
export const ConnectedDiscoverLink = React.memo(() => {
@ -29,9 +29,9 @@ export const ConnectedDiscoverLink = React.memo(() => {
services: { discover },
} = useKibanaContextForPlugin();
const [pageState] = useActor(useObservabilityLogExplorerPageStateContext());
const [pageState] = useActor(useObservabilityLogsExplorerPageStateContext());
if (pageState.matches({ initialized: 'validLogExplorerState' })) {
if (pageState.matches({ initialized: 'validLogsExplorerState' })) {
return <DiscoverLinkForValidState discover={discover} pageState={pageState} />;
} else {
return <DiscoverLinkForUnknownState />;
@ -39,15 +39,15 @@ export const ConnectedDiscoverLink = React.memo(() => {
});
type InitializedPageState = MatchedStateFromActor<
ObservabilityLogExplorerService,
{ initialized: 'validLogExplorerState' }
ObservabilityLogsExplorerService,
{ initialized: 'validLogsExplorerState' }
>;
export const DiscoverLinkForValidState = React.memo(
({
discover,
pageState: {
context: { logExplorerState },
context: { logsExplorerState },
},
}: {
discover: DiscoverStart;
@ -55,15 +55,15 @@ export const DiscoverLinkForValidState = React.memo(
}) => {
const discoverLinkParams = useMemo<DiscoverAppLocatorParams>(
() => ({
breakdownField: logExplorerState.chart.breakdownField ?? undefined,
columns: getDiscoverColumnsFromDisplayOptions(logExplorerState),
filters: getDiscoverFiltersFromState(logExplorerState.filters, logExplorerState.controls),
query: logExplorerState.query,
refreshInterval: logExplorerState.refreshInterval,
timeRange: logExplorerState.time,
dataViewSpec: hydrateDatasetSelection(logExplorerState.datasetSelection).toDataviewSpec(),
breakdownField: logsExplorerState.chart.breakdownField ?? undefined,
columns: getDiscoverColumnsFromDisplayOptions(logsExplorerState),
filters: getDiscoverFiltersFromState(logsExplorerState.filters, logsExplorerState.controls),
query: logsExplorerState.query,
refreshInterval: logsExplorerState.refreshInterval,
timeRange: logsExplorerState.time,
dataViewSpec: hydrateDatasetSelection(logsExplorerState.datasetSelection).toDataviewSpec(),
}),
[logExplorerState]
[logsExplorerState]
);
return <DiscoverLink discover={discover} discoverLinkParams={discoverLinkParams} />;

View file

@ -27,7 +27,7 @@ import { ConnectedDiscoverLink } from './discover_link';
import { FeedbackLink } from './feedback_link';
import { ConnectedOnboardingLink } from './onboarding_link';
export const LogExplorerTopNavMenu = () => {
export const LogsExplorerTopNavMenu = () => {
const {
services: { serverless },
} = useKibanaContextForPlugin();

View file

@ -10,7 +10,7 @@ import { css } from '@emotion/react';
import React from 'react';
import { useKibanaContextForPlugin } from '../utils/use_kibana';
export const ObservabilityLogExplorerPageTemplate = ({
export const ObservabilityLogsExplorerPageTemplate = ({
children,
pageProps,
}: React.PropsWithChildren<{

View file

@ -6,9 +6,9 @@
*/
import { PluginInitializerContext } from '@kbn/core/public';
import { ObservabilityLogExplorerConfig } from '../common/plugin_config';
import { ObservabilityLogExplorerPlugin } from './plugin';
import { ObservabilityLogsExplorerConfig } from '../common/plugin_config';
import { ObservabilityLogsExplorerPlugin } from './plugin';
export function plugin(context: PluginInitializerContext<ObservabilityLogExplorerConfig>) {
return new ObservabilityLogExplorerPlugin(context);
export function plugin(context: PluginInitializerContext<ObservabilityLogsExplorerConfig>) {
return new ObservabilityLogsExplorerPlugin(context);
}

View file

@ -8,10 +8,10 @@
import { CreateLogsExplorerController } from '@kbn/logs-explorer-plugin/public';
import { renderFlyoutContent } from './flyout_content';
export const createLogExplorerControllerWithCustomizations =
(createLogExplorerController: CreateLogsExplorerController): CreateLogsExplorerController =>
export const createLogsExplorerControllerWithCustomizations =
(createLogsExplorerController: CreateLogsExplorerController): CreateLogsExplorerController =>
(args) =>
createLogExplorerController({
createLogsExplorerController({
...args,
customizations: {
...args.customizations,

View file

@ -20,35 +20,35 @@ import {
ObservabilityLogsExplorerLocators,
SingleDatasetLocatorDefinition,
} from '../common/locators';
import { type ObservabilityLogExplorerConfig } from '../common/plugin_config';
import { logExplorerAppTitle } from '../common/translations';
import { type ObservabilityLogsExplorerConfig } from '../common/plugin_config';
import { logsExplorerAppTitle } from '../common/translations';
import type {
ObservabilityLogExplorerAppMountParameters,
ObservabilityLogExplorerPluginSetup,
ObservabilityLogExplorerPluginStart,
ObservabilityLogExplorerSetupDeps,
ObservabilityLogExplorerStartDeps,
ObservabilityLogsExplorerAppMountParameters,
ObservabilityLogsExplorerPluginSetup,
ObservabilityLogsExplorerPluginStart,
ObservabilityLogsExplorerSetupDeps,
ObservabilityLogsExplorerStartDeps,
} from './types';
export class ObservabilityLogExplorerPlugin
implements Plugin<ObservabilityLogExplorerPluginSetup, ObservabilityLogExplorerPluginStart>
export class ObservabilityLogsExplorerPlugin
implements Plugin<ObservabilityLogsExplorerPluginSetup, ObservabilityLogsExplorerPluginStart>
{
private config: ObservabilityLogExplorerConfig;
private config: ObservabilityLogsExplorerConfig;
private locators?: ObservabilityLogsExplorerLocators;
constructor(context: PluginInitializerContext<ObservabilityLogExplorerConfig>) {
constructor(context: PluginInitializerContext<ObservabilityLogsExplorerConfig>) {
this.config = context.config.get();
}
public setup(
core: CoreSetup<ObservabilityLogExplorerStartDeps, ObservabilityLogExplorerPluginStart>,
_pluginsSetup: ObservabilityLogExplorerSetupDeps
core: CoreSetup<ObservabilityLogsExplorerStartDeps, ObservabilityLogsExplorerPluginStart>,
_pluginsSetup: ObservabilityLogsExplorerSetupDeps
) {
const { share, serverless, discover } = _pluginsSetup;
const useHash = core.uiSettings.get('state:storeInSessionStorage');
core.application.register({
id: OBSERVABILITY_LOGS_EXPLORER_APP_ID,
title: logExplorerAppTitle,
title: logsExplorerAppTitle,
category: DEFAULT_APP_CATEGORIES.observability,
euiIconType: 'logoLogging',
navLinkStatus: this.config.navigation.showAppLink
@ -56,13 +56,13 @@ export class ObservabilityLogExplorerPlugin
: AppNavLinkStatus.hidden,
searchable: true,
keywords: ['logs', 'log', 'explorer', 'logs explorer'],
mount: async (appMountParams: ObservabilityLogExplorerAppMountParameters) => {
mount: async (appMountParams: ObservabilityLogsExplorerAppMountParameters) => {
const [coreStart, pluginsStart, ownPluginStart] = await core.getStartServices();
const { renderObservabilityLogExplorer } = await import(
'./applications/observability_log_explorer'
const { renderObservabilityLogsExplorer } = await import(
'./applications/observability_logs_explorer'
);
return renderObservabilityLogExplorer(
return renderObservabilityLogsExplorer(
coreStart,
pluginsStart,
ownPluginStart,
@ -74,15 +74,15 @@ export class ObservabilityLogExplorerPlugin
// App used solely to redirect from "/app/observability-log-explorer" to "/app/observability-logs-explorer"
core.application.register({
id: 'observability-log-explorer',
title: logExplorerAppTitle,
title: logsExplorerAppTitle,
navLinkStatus: AppNavLinkStatus.hidden,
mount: async (appMountParams: AppMountParameters) => {
const [coreStart] = await core.getStartServices();
const { renderObservabilityLogExplorerRedirect } = await import(
const { renderObservabilityLogsExplorerRedirect } = await import(
'./applications/redirect_to_observability_logs_explorer'
);
return renderObservabilityLogExplorerRedirect(coreStart, appMountParams);
return renderObservabilityLogsExplorerRedirect(coreStart, appMountParams);
},
});
@ -112,7 +112,7 @@ export class ObservabilityLogExplorerPlugin
};
}
public start(_core: CoreStart, _pluginsStart: ObservabilityLogExplorerStartDeps) {
public start(_core: CoreStart, _pluginsStart: ObservabilityLogsExplorerStartDeps) {
return {};
}
}

View file

@ -14,7 +14,7 @@ import { FormattedMessage } from '@kbn/i18n-react';
import { useLinkProps } from '@kbn/observability-shared-plugin/public';
import { useActor } from '@xstate/react';
import React from 'react';
import { ObservabilityLogExplorerPageTemplate } from '../../components/page_template';
import { ObservabilityLogsExplorerPageTemplate } from '../../components/page_template';
import {
ObservabilityDatasetQualityPageStateProvider,
useObservabilityDatasetQualityPageStateContext,
@ -30,13 +30,13 @@ export interface DatasetQualityRouteProps {
export const DatasetQualityRoute = () => {
const { services } = useKibanaContextForPlugin();
const { datasetQuality, serverless, chrome, notifications } = services;
const logExplorerLinkProps = useLinkProps({ app: OBSERVABILITY_LOGS_EXPLORER_APP_ID });
const logsExplorerLinkProps = useLinkProps({ app: OBSERVABILITY_LOGS_EXPLORER_APP_ID });
useBreadcrumbs(
[
{
text: 'Datasets',
...logExplorerLinkProps,
...logsExplorerLinkProps,
},
],
chrome,
@ -78,7 +78,7 @@ const ConnectedContent = React.memo(() => {
});
const InitializingContent = React.memo(() => (
<ObservabilityLogExplorerPageTemplate>
<ObservabilityLogsExplorerPageTemplate>
<EuiEmptyPrompt
icon={<EuiLoadingLogo logo="logoKibana" size="xl" />}
title={
@ -88,7 +88,7 @@ const InitializingContent = React.memo(() => (
/>
}
/>
</ObservabilityLogExplorerPageTemplate>
</ObservabilityLogsExplorerPageTemplate>
));
const InitializedContent = React.memo(
@ -100,9 +100,9 @@ const InitializedContent = React.memo(
datasetQualityController: DatasetQualityController;
}) => {
return (
<ObservabilityLogExplorerPageTemplate pageProps={{ paddingSize: 'l' }}>
<ObservabilityLogsExplorerPageTemplate pageProps={{ paddingSize: 'l' }}>
<datasetQuality.DatasetQuality controller={datasetQualityController} />
</ObservabilityLogExplorerPageTemplate>
</ObservabilityLogsExplorerPageTemplate>
);
}
);

View file

@ -12,20 +12,20 @@ import type {
} from '@kbn/logs-explorer-plugin/public';
import { useActor } from '@xstate/react';
import React, { useMemo } from 'react';
import { LogExplorerTopNavMenu } from '../../components/log_explorer_top_nav_menu';
import { ObservabilityLogExplorerPageTemplate } from '../../components/page_template';
import { createLogExplorerControllerWithCustomizations } from '../../log_explorer_customizations';
import { LogsExplorerTopNavMenu } from '../../components/logs_explorer_top_nav_menu';
import { ObservabilityLogsExplorerPageTemplate } from '../../components/page_template';
import { createLogsExplorerControllerWithCustomizations } from '../../logs_explorer_customizations';
import {
ObservabilityLogExplorerPageStateProvider,
useObservabilityLogExplorerPageStateContext,
} from '../../state_machines/observability_log_explorer/src';
ObservabilityLogsExplorerPageStateProvider,
useObservabilityLogsExplorerPageStateContext,
} from '../../state_machines/observability_logs_explorer/src';
import { LazyOriginInterpreter } from '../../state_machines/origin_interpreter/src/lazy_component';
import { ObservabilityLogExplorerHistory } from '../../types';
import { ObservabilityLogsExplorerHistory } from '../../types';
import { noBreadcrumbs, useBreadcrumbs } from '../../utils/breadcrumbs';
import { useKbnUrlStateStorageFromRouterContext } from '../../utils/kbn_url_state_context';
import { useKibanaContextForPlugin } from '../../utils/use_kibana';
export const ObservabilityLogExplorerMainRoute = () => {
export const ObservabilityLogsExplorerMainRoute = () => {
const { services } = useKibanaContextForPlugin();
const { logsExplorer, serverless, chrome, notifications, appParams } = services;
const { history } = appParams;
@ -34,22 +34,22 @@ export const ObservabilityLogExplorerMainRoute = () => {
const urlStateStorageContainer = useKbnUrlStateStorageFromRouterContext();
const createLogExplorerController = useMemo(
() => createLogExplorerControllerWithCustomizations(logsExplorer.createLogsExplorerController),
const createLogsExplorerController = useMemo(
() => createLogsExplorerControllerWithCustomizations(logsExplorer.createLogsExplorerController),
[logsExplorer.createLogsExplorerController]
);
return (
<ObservabilityLogExplorerPageStateProvider
createLogExplorerController={createLogExplorerController}
<ObservabilityLogsExplorerPageStateProvider
createLogsExplorerController={createLogsExplorerController}
toasts={notifications.toasts}
urlStateStorageContainer={urlStateStorageContainer}
timeFilterService={services.data.query.timefilter.timefilter}
>
<LogExplorerTopNavMenu />
<LogsExplorerTopNavMenu />
<LazyOriginInterpreter history={history} toasts={notifications.toasts} />
<ConnectedContent />
</ObservabilityLogExplorerPageStateProvider>
</ObservabilityLogsExplorerPageStateProvider>
);
};
@ -61,14 +61,14 @@ const ConnectedContent = React.memo(() => {
},
} = useKibanaContextForPlugin();
const [state] = useActor(useObservabilityLogExplorerPageStateContext());
const [state] = useActor(useObservabilityLogsExplorerPageStateContext());
if (state.matches('initialized')) {
return (
<InitializedContent
logExplorerController={state.context.controller}
logsExplorerController={state.context.controller}
history={history}
logExplorer={logsExplorer}
logsExplorer={logsExplorer}
/>
);
} else {
@ -77,7 +77,7 @@ const ConnectedContent = React.memo(() => {
});
const InitializingContent = React.memo(() => (
<ObservabilityLogExplorerPageTemplate>
<ObservabilityLogsExplorerPageTemplate>
<EuiEmptyPrompt
icon={<EuiLoadingLogo logo="logoKibana" size="xl" />}
title={
@ -87,23 +87,23 @@ const InitializingContent = React.memo(() => (
/>
}
/>
</ObservabilityLogExplorerPageTemplate>
</ObservabilityLogsExplorerPageTemplate>
));
const InitializedContent = React.memo(
({
history,
logExplorer,
logExplorerController,
logsExplorer,
logsExplorerController,
}: {
history: ObservabilityLogExplorerHistory;
logExplorer: LogsExplorerPluginStart;
logExplorerController: LogsExplorerController;
history: ObservabilityLogsExplorerHistory;
logsExplorer: LogsExplorerPluginStart;
logsExplorerController: LogsExplorerController;
}) => {
return (
<ObservabilityLogExplorerPageTemplate>
<logExplorer.LogsExplorer controller={logExplorerController} scopedHistory={history} />
</ObservabilityLogExplorerPageTemplate>
<ObservabilityLogsExplorerPageTemplate>
<logsExplorer.LogsExplorer controller={logsExplorerController} scopedHistory={history} />
</ObservabilityLogsExplorerPageTemplate>
);
}
);

View file

@ -1,30 +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; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import { getDevToolsOptions } from '@kbn/xstate-utils';
import { useInterpret } from '@xstate/react';
import createContainer from 'constate';
import {
createObservabilityLogExplorerStateMachine,
ObservabilityLogExplorerStateMachineDependencies,
} from './state_machine';
export const useObservabilityLogExplorerPageState = (
deps: ObservabilityLogExplorerStateMachineDependencies
) => {
const observabilityLogExplorerPageStateService = useInterpret(
() => createObservabilityLogExplorerStateMachine(deps),
{ devTools: getDevToolsOptions() }
);
return observabilityLogExplorerPageStateService;
};
export const [
ObservabilityLogExplorerPageStateProvider,
useObservabilityLogExplorerPageStateContext,
] = createContainer(useObservabilityLogExplorerPageState);

View file

@ -7,18 +7,18 @@
import type { CreateLogsExplorerController } from '@kbn/logs-explorer-plugin/public';
import type { InvokeCreator } from 'xstate';
import type { ObservabilityLogExplorerContext, ObservabilityLogExplorerEvent } from './types';
import type { ObservabilityLogsExplorerContext, ObservabilityLogsExplorerEvent } from './types';
export const createController =
({
createLogExplorerController,
createLogsExplorerController,
}: {
createLogExplorerController: CreateLogsExplorerController;
}): InvokeCreator<ObservabilityLogExplorerContext, ObservabilityLogExplorerEvent> =>
createLogsExplorerController: CreateLogsExplorerController;
}): InvokeCreator<ObservabilityLogsExplorerContext, ObservabilityLogsExplorerEvent> =>
(context, event) =>
(send) => {
createLogExplorerController({
initialState: context.initialLogExplorerState,
createLogsExplorerController({
initialState: context.initialLogsExplorerState,
}).then((controller) => {
send({
type: 'CONTROLLER_CREATED',
@ -27,9 +27,9 @@ export const createController =
});
};
export const subscribeToLogExplorerState: InvokeCreator<
ObservabilityLogExplorerContext,
ObservabilityLogExplorerEvent
export const subscribeToLogsExplorerState: InvokeCreator<
ObservabilityLogsExplorerContext,
ObservabilityLogsExplorerEvent
> = (context, event) => (send) => {
if (!('controller' in context)) {
throw new Error('Failed to subscribe to controller: no controller in context');
@ -39,7 +39,7 @@ export const subscribeToLogExplorerState: InvokeCreator<
const subscription = controller.state$.subscribe({
next: (state) => {
send({ type: 'LOG_EXPLORER_STATE_CHANGED', state });
send({ type: 'LOGS_EXPLORER_STATE_CHANGED', state });
},
});

View file

@ -5,8 +5,8 @@
* 2.0.
*/
import { CommonObservabilityLogExplorerContext } from './types';
import { CommonObservabilityLogsExplorerContext } from './types';
export const DEFAULT_CONTEXT: CommonObservabilityLogExplorerContext = {
initialLogExplorerState: {},
export const DEFAULT_CONTEXT: CommonObservabilityLogsExplorerContext = {
initialLogsExplorerState: {},
};

View file

@ -0,0 +1,30 @@
/*
* 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 { getDevToolsOptions } from '@kbn/xstate-utils';
import { useInterpret } from '@xstate/react';
import createContainer from 'constate';
import {
createObservabilityLogsExplorerStateMachine,
ObservabilityLogsExplorerStateMachineDependencies,
} from './state_machine';
export const useObservabilityLogsExplorerPageState = (
deps: ObservabilityLogsExplorerStateMachineDependencies
) => {
const observabilityLogsExplorerPageStateService = useInterpret(
() => createObservabilityLogsExplorerStateMachine(deps),
{ devTools: getDevToolsOptions() }
);
return observabilityLogsExplorerPageStateService;
};
export const [
ObservabilityLogsExplorerPageStateProvider,
useObservabilityLogsExplorerPageStateContext,
] = createContainer(useObservabilityLogsExplorerPageState);

View file

@ -12,27 +12,27 @@ import { actions, createMachine, InterpreterFrom } from 'xstate';
import { TimefilterContract } from '@kbn/data-plugin/public';
import { DEFAULT_CONTEXT } from './defaults';
import {
ObservabilityLogExplorerContext,
ObservabilityLogExplorerEvent,
ObservabilityLogExplorerTypeState,
ObservabilityLogsExplorerContext,
ObservabilityLogsExplorerEvent,
ObservabilityLogsExplorerTypeState,
} from './types';
import { initializeFromUrl, updateUrlFromLogExplorerState } from './url_state_storage_service';
import { createController, subscribeToLogExplorerState } from './controller_service';
import { initializeFromUrl, updateUrlFromLogsExplorerState } from './url_state_storage_service';
import { createController, subscribeToLogsExplorerState } from './controller_service';
import { initializeFromTimeFilterService } from './time_filter_service';
export const createPureObservabilityLogExplorerStateMachine = (
initialContext: ObservabilityLogExplorerContext
export const createPureObservabilityLogsExplorerStateMachine = (
initialContext: ObservabilityLogsExplorerContext
) =>
/** @xstate-layout N4IgpgJg5mDOIC5QHkBGswCcBuBDVAlgDYEAuAngDID2UAogB4AOR1mWAdAK4B2BfpArhIAvSAGIA2gAYAuolBNqsMgWo8FIBogDMOjgFYAbAEZpAdgCcRgwBYAHAcsGANCHK7bHWztsGTRjomevbmRpYAvhFuaBg4+MRkVLSMLGyc-KrCBCL8UABimNQAtgAqBMVg+cSkWADKWNgEAMZg4gCSAHLtpe0AgpTtAFp0ACIA+vkASsgAsuO9s3ST7ZSldFPjdRsAau0AwnQy8kggSiqC6praCAC0ZvrhRua24Tp2jiZuHggATEb2Dj-aQ2PQmcEGSFRGLoRoJEgUGj0ZisdiYDiZQTZXI8ApFYoAVUwRA63V6A2GY0mM3mBKmlGOmnOqiupxutx0Rg49ksv2kBl+9hMQp0oV+30QBnsXgsAX8lhevx0lki0RAsThhARyWRaTRHGa7Fwglx+3UpCKRCIWHE+2QnVKM0olA2432UzofXWo0Zp2Zlw0bMQt0FHCMAN85jC9k5tl+cYlCFCJg4QRMxnM0lsZkcRmh6th8S1SSRqVRGQEQlEkG4PAA1jxqAB3HillHpTB1UjGtqUZAAcXGdAAGgAFPsezZ1Upe5b7AASfU6-bGvsUyhZgdANyVBg4JmzRl+UtFFks9nsiYh0n3tn59lM-2FNnzGqLiURKXb+sxVZyNbwEgIDbPV6m7WpxD7QcR3HZBJy2Gd1jdRdl1XOQmQ3ANrklUxDFCSxDwVX4TAIq9BXMIFnnTc9gXseMojVRsIDgTQ3zwYtP11ctMAwi41C3LRg3TFMnheN4Pn8RN7h0CjpDk6QDyFcxiOkX5VRhOJ2I-HUyw7Wtf2xSBeM3bCEAot4LyFHl42cEEpNsSxDHkkwlTMKwH2cV9Cy07UQO4jFK2xPJChKcpKmqIhak7RoWjAYysKDO57Bvayswc0EDxeMiuVscwdEFAUBRci9fi8zT4RLL9QPRAzRGC-EiSIeL+NMjkuXeNT3PDF5fFcdxEDjFNlNBSxwQvXKdDKzVtL8vTDTAY08jNHgLWoK0sGa1lt2DTkOGsJUHNGuSSJ8RMXhTEw8t8S61LkpwpvfXyqv82r-wgTaBPZOjvGSz49F5RxzEvfqEDMdMwzvBwAnMAwoxIh6fMqri9NesQIFrBtm1bZ6Oy7HsPta3wfukP7lQKoGr2fDhpEsTllNCAwdAUya1TYirON0n9AurdHAIIYCcbRPHagJxKjBp-cDCzA9LDuqxLEph9qdp55yMZhSDAYiIgA */
createMachine<
ObservabilityLogExplorerContext,
ObservabilityLogExplorerEvent,
ObservabilityLogExplorerTypeState
ObservabilityLogsExplorerContext,
ObservabilityLogsExplorerEvent,
ObservabilityLogsExplorerTypeState
>(
{
context: initialContext,
predictableActionArguments: true,
id: 'ObservabilityLogExplorer',
id: 'ObservabilityLogsExplorer',
initial: 'uninitialized',
states: {
uninitialized: {
@ -74,31 +74,31 @@ export const createPureObservabilityLogExplorerStateMachine = (
},
initialized: {
invoke: {
src: 'subscribeToLogExplorerState',
src: 'subscribeToLogsExplorerState',
},
states: {
unknownLogExplorerState: {
unknownLogsExplorerState: {
on: {
LOG_EXPLORER_STATE_CHANGED: {
target: 'validLogExplorerState',
actions: ['storeLogExplorerState', 'updateUrlFromLogExplorerState'],
LOGS_EXPLORER_STATE_CHANGED: {
target: 'validLogsExplorerState',
actions: ['storeLogsExplorerState', 'updateUrlFromLogsExplorerState'],
},
},
},
validLogExplorerState: {
validLogsExplorerState: {
on: {
LOG_EXPLORER_STATE_CHANGED: {
actions: ['storeLogExplorerState', 'updateUrlFromLogExplorerState'],
target: 'validLogExplorerState',
LOGS_EXPLORER_STATE_CHANGED: {
actions: ['storeLogsExplorerState', 'updateUrlFromLogsExplorerState'],
target: 'validLogsExplorerState',
internal: true,
},
},
},
},
initial: 'unknownLogExplorerState',
initial: 'unknownLogsExplorerState',
},
},
},
@ -114,8 +114,10 @@ export const createPureObservabilityLogExplorerStateMachine = (
'refreshInterval' in event &&
event.type === 'INITIALIZED_FROM_TIME_FILTER_SERVICE'
? {
initialLogExplorerState: {
...('initialLogExplorerState' in context ? context.initialLogExplorerState : {}),
initialLogsExplorerState: {
...('initialLogsExplorerState' in context
? context.initialLogsExplorerState
: {}),
...{ time: event.time, refreshInterval: event.refreshInterval },
},
}
@ -124,16 +126,18 @@ export const createPureObservabilityLogExplorerStateMachine = (
storeInitialUrlState: actions.assign((context, event) => {
return 'stateFromUrl' in event && event.type === 'INITIALIZED_FROM_URL'
? {
initialLogExplorerState: {
...('initialLogExplorerState' in context ? context.initialLogExplorerState : {}),
initialLogsExplorerState: {
...('initialLogsExplorerState' in context
? context.initialLogsExplorerState
: {}),
...event.stateFromUrl,
},
}
: {};
}),
storeLogExplorerState: actions.assign((context, event) => {
return 'state' in event && event.type === 'LOG_EXPLORER_STATE_CHANGED'
? { logExplorerState: event.state }
storeLogsExplorerState: actions.assign((context, event) => {
return 'state' in event && event.type === 'LOGS_EXPLORER_STATE_CHANGED'
? { logsExplorerState: event.state }
: {};
}),
},
@ -141,33 +145,33 @@ export const createPureObservabilityLogExplorerStateMachine = (
}
);
export interface ObservabilityLogExplorerStateMachineDependencies {
createLogExplorerController: CreateLogsExplorerController;
initialContext?: ObservabilityLogExplorerContext;
export interface ObservabilityLogsExplorerStateMachineDependencies {
createLogsExplorerController: CreateLogsExplorerController;
initialContext?: ObservabilityLogsExplorerContext;
timeFilterService: TimefilterContract;
toasts: IToasts;
urlStateStorageContainer: IKbnUrlStateStorage;
}
export const createObservabilityLogExplorerStateMachine = ({
export const createObservabilityLogsExplorerStateMachine = ({
initialContext = DEFAULT_CONTEXT,
toasts,
urlStateStorageContainer,
createLogExplorerController,
createLogsExplorerController,
timeFilterService,
}: ObservabilityLogExplorerStateMachineDependencies) =>
createPureObservabilityLogExplorerStateMachine(initialContext).withConfig({
}: ObservabilityLogsExplorerStateMachineDependencies) =>
createPureObservabilityLogsExplorerStateMachine(initialContext).withConfig({
actions: {
updateUrlFromLogExplorerState: updateUrlFromLogExplorerState({ urlStateStorageContainer }),
updateUrlFromLogsExplorerState: updateUrlFromLogsExplorerState({ urlStateStorageContainer }),
},
services: {
createController: createController({ createLogExplorerController }),
createController: createController({ createLogsExplorerController }),
initializeFromTimeFilterService: initializeFromTimeFilterService({ timeFilterService }),
initializeFromUrl: initializeFromUrl({ urlStateStorageContainer, toastsService: toasts }),
subscribeToLogExplorerState,
subscribeToLogsExplorerState,
},
});
export type ObservabilityLogExplorerService = InterpreterFrom<
typeof createObservabilityLogExplorerStateMachine
export type ObservabilityLogsExplorerService = InterpreterFrom<
typeof createObservabilityLogsExplorerStateMachine
>;

View file

@ -7,14 +7,14 @@
import { TimefilterContract } from '@kbn/data-plugin/public';
import { InvokeCreator } from 'xstate';
import { ObservabilityLogExplorerContext, ObservabilityLogExplorerEvent } from './types';
import { ObservabilityLogsExplorerContext, ObservabilityLogsExplorerEvent } from './types';
export const initializeFromTimeFilterService =
({
timeFilterService,
}: {
timeFilterService: TimefilterContract;
}): InvokeCreator<ObservabilityLogExplorerContext, ObservabilityLogExplorerEvent> =>
}): InvokeCreator<ObservabilityLogsExplorerContext, ObservabilityLogsExplorerEvent> =>
(_context, _event) =>
(send) => {
const time = timeFilterService.getTime();

View file

@ -12,21 +12,21 @@ import {
LogsExplorerPublicStateUpdate,
} from '@kbn/logs-explorer-plugin/public';
export type ObservabilityLogExplorerContext = ObservabilityLogExplorerTypeState['context'];
export type ObservabilityLogsExplorerContext = ObservabilityLogsExplorerTypeState['context'];
export interface CommonObservabilityLogExplorerContext {
initialLogExplorerState: LogsExplorerPublicStateUpdate;
export interface CommonObservabilityLogsExplorerContext {
initialLogsExplorerState: LogsExplorerPublicStateUpdate;
}
export interface WithLogExplorerState {
logExplorerState: LogsExplorerPublicState;
export interface WithLogsExplorerState {
logsExplorerState: LogsExplorerPublicState;
}
export interface WithController {
controller: LogsExplorerController;
}
export type ObservabilityLogExplorerEvent =
export type ObservabilityLogsExplorerEvent =
| {
type: 'INITIALIZED_FROM_URL';
stateFromUrl?: LogsExplorerPublicStateUpdate;
@ -41,24 +41,24 @@ export type ObservabilityLogExplorerEvent =
controller: LogsExplorerController;
}
| {
type: 'LOG_EXPLORER_STATE_CHANGED';
type: 'LOGS_EXPLORER_STATE_CHANGED';
state: LogsExplorerPublicState;
};
export type ObservabilityLogExplorerTypeState =
export type ObservabilityLogsExplorerTypeState =
| {
value:
| 'uninitialized'
| 'initializingFromUrl'
| 'initializingFromTimeFilterService'
| 'creatingController';
context: CommonObservabilityLogExplorerContext;
context: CommonObservabilityLogsExplorerContext;
}
| {
value: 'initialized' | { initialized: 'unknownLogExplorerState' };
context: CommonObservabilityLogExplorerContext & WithController;
value: 'initialized' | { initialized: 'unknownLogsExplorerState' };
context: CommonObservabilityLogsExplorerContext & WithController;
}
| {
value: { initialized: 'validLogExplorerState' };
context: CommonObservabilityLogExplorerContext & WithLogExplorerState & WithController;
value: { initialized: 'validLogsExplorerState' };
context: CommonObservabilityLogsExplorerContext & WithLogsExplorerState & WithController;
};

View file

@ -12,24 +12,24 @@ import * as Either from 'fp-ts/lib/Either';
import * as rt from 'io-ts';
import { InvokeCreator } from 'xstate';
import { OBSERVABILITY_LOGS_EXPLORER_URL_STATE_KEY } from '../../../../common';
import type { ObservabilityLogExplorerContext, ObservabilityLogExplorerEvent } from './types';
import type { ObservabilityLogsExplorerContext, ObservabilityLogsExplorerEvent } from './types';
import * as urlSchemaV1 from './url_schema_v1';
interface ObservabilityLogExplorerUrlStateDependencies {
interface ObservabilityLogsExplorerUrlStateDependencies {
toastsService: IToasts;
urlStateStorageContainer: IKbnUrlStateStorage;
}
export const updateUrlFromLogExplorerState =
export const updateUrlFromLogsExplorerState =
({ urlStateStorageContainer }: { urlStateStorageContainer: IKbnUrlStateStorage }) =>
(context: ObservabilityLogExplorerContext, event: ObservabilityLogExplorerEvent) => {
if (!('logExplorerState' in context)) {
(context: ObservabilityLogsExplorerContext, event: ObservabilityLogsExplorerEvent) => {
if (!('logsExplorerState' in context)) {
return;
}
// we want to write in the newest schema
const encodedUrlStateValues = urlSchemaV1.stateFromUntrustedUrlRT.encode(
context.logExplorerState
context.logsExplorerState
);
urlStateStorageContainer.set(OBSERVABILITY_LOGS_EXPLORER_URL_STATE_KEY, encodedUrlStateValues, {
@ -41,9 +41,9 @@ export const initializeFromUrl =
({
toastsService,
urlStateStorageContainer,
}: ObservabilityLogExplorerUrlStateDependencies): InvokeCreator<
ObservabilityLogExplorerContext,
ObservabilityLogExplorerEvent
}: ObservabilityLogsExplorerUrlStateDependencies): InvokeCreator<
ObservabilityLogsExplorerContext,
ObservabilityLogsExplorerEvent
> =>
(_context, _event) =>
(send) => {

View file

@ -6,14 +6,14 @@
*/
import { InvokeCreator } from 'xstate';
import { ObservabilityLogExplorerHistory } from '../../../types';
import { ObservabilityLogsExplorerHistory } from '../../../types';
import { OriginInterpreterContext, OriginInterpreterEvent } from './types';
export const initializeFromLocationState =
({
history,
}: {
history: ObservabilityLogExplorerHistory;
history: ObservabilityLogsExplorerHistory;
}): InvokeCreator<OriginInterpreterContext, OriginInterpreterEvent> =>
(context, event) =>
(callback) => {

View file

@ -30,7 +30,7 @@ export const createRequestFeedbackNotifier = (toasts: IToasts) => () => {
<EuiFlexGroup justifyContent="flexEnd" gutterSize="s">
<EuiFlexItem grow={false}>
<EuiButton
data-test-subj="observabilityLogExplorerFeedbackToastButton"
data-test-subj="observabilityLogsExplorerFeedbackToastButton"
href={LOGS_ONBOARDING_FEEDBACK_LINK}
size="s"
target="_blank"

View file

@ -7,7 +7,7 @@
import { IToasts } from '@kbn/core-notifications-browser';
import { createMachine, InterpreterFrom } from 'xstate';
import { ObservabilityLogExplorerHistory } from '../../../types';
import { ObservabilityLogsExplorerHistory } from '../../../types';
import { FEEDBACK_DELAY_MS } from './constants';
import { DEFAULT_CONTEXT } from './defaults';
import { initializeFromLocationState } from './location_state_service';
@ -67,7 +67,7 @@ export const createPureOriginInterpreterStateMachine = (initialContext: OriginIn
export interface OriginInterpreterStateMachineDependencies {
initialContext?: OriginInterpreterContext;
history: ObservabilityLogExplorerHistory;
history: ObservabilityLogsExplorerHistory;
toasts: IToasts;
}

View file

@ -20,20 +20,20 @@ import {
ObservabilityLogsExplorerLocationState,
} from '../common/locators';
export interface ObservabilityLogExplorerPluginSetup {
export interface ObservabilityLogsExplorerPluginSetup {
locators: ObservabilityLogsExplorerLocators;
}
// eslint-disable-next-line @typescript-eslint/no-empty-interface
export interface ObservabilityLogExplorerPluginStart {}
export interface ObservabilityLogsExplorerPluginStart {}
export interface ObservabilityLogExplorerSetupDeps {
export interface ObservabilityLogsExplorerSetupDeps {
discover: DiscoverSetup;
serverless?: ServerlessPluginStart;
share: SharePluginSetup;
}
export interface ObservabilityLogExplorerStartDeps {
export interface ObservabilityLogsExplorerStartDeps {
data: DataPublicPluginStart;
discover: DiscoverStart;
logsExplorer: LogsExplorerPluginStart;
@ -45,6 +45,7 @@ export interface ObservabilityLogExplorerStartDeps {
datasetQuality: DatasetQualityPluginStart;
}
export type ObservabilityLogExplorerHistory = ScopedHistory<ObservabilityLogsExplorerLocationState>;
export type ObservabilityLogExplorerAppMountParameters =
export type ObservabilityLogsExplorerHistory =
ScopedHistory<ObservabilityLogsExplorerLocationState>;
export type ObservabilityLogsExplorerAppMountParameters =
AppMountParameters<ObservabilityLogsExplorerLocationState>;

View file

@ -16,7 +16,7 @@ import { useLinkProps } from '@kbn/observability-shared-plugin/public';
import type { ServerlessPluginStart } from '@kbn/serverless/public';
import { useEffect } from 'react';
import {
logExplorerAppTitle,
logsExplorerAppTitle,
logsAppTitle,
observabilityAppTitle,
} from '../../common/translations';
@ -28,7 +28,7 @@ export const useBreadcrumbs = (
) => {
const observabilityLinkProps = useLinkProps({ app: OBSERVABILITY_OVERVIEW_APP_ID });
const logsLinkProps = useLinkProps({ app: LOGS_APP_ID });
const logExplorerLinkProps = useLinkProps({ app: OBSERVABILITY_LOGS_EXPLORER_APP_ID });
const logsExplorerLinkProps = useLinkProps({ app: OBSERVABILITY_LOGS_EXPLORER_APP_ID });
useEffect(() => {
setBreadcrumbs(
@ -44,8 +44,8 @@ export const useBreadcrumbs = (
...logsLinkProps,
},
{
text: logExplorerAppTitle,
...logExplorerLinkProps,
text: logsExplorerAppTitle,
...logsExplorerLinkProps,
},
...breadcrumbs,
],

View file

@ -13,22 +13,22 @@ import {
} from '@kbn/kibana-react-plugin/public';
import { useMemo } from 'react';
import {
ObservabilityLogExplorerAppMountParameters,
ObservabilityLogExplorerPluginStart,
ObservabilityLogExplorerStartDeps,
ObservabilityLogsExplorerAppMountParameters,
ObservabilityLogsExplorerPluginStart,
ObservabilityLogsExplorerStartDeps,
} from '../types';
export type PluginKibanaContextValue = CoreStart &
ObservabilityLogExplorerStartDeps &
ObservabilityLogExplorerPluginStart & {
appParams: ObservabilityLogExplorerAppMountParameters;
ObservabilityLogsExplorerStartDeps &
ObservabilityLogsExplorerPluginStart & {
appParams: ObservabilityLogsExplorerAppMountParameters;
};
export const createKibanaContextForPlugin = (
core: CoreStart,
plugins: ObservabilityLogExplorerStartDeps,
pluginStart: ObservabilityLogExplorerPluginStart,
appParams: ObservabilityLogExplorerAppMountParameters
plugins: ObservabilityLogsExplorerStartDeps,
pluginStart: ObservabilityLogsExplorerPluginStart,
appParams: ObservabilityLogsExplorerAppMountParameters
) =>
createKibanaReactContext<PluginKibanaContextValue>({
...core,
@ -42,9 +42,9 @@ export const useKibanaContextForPlugin =
export const useKibanaContextForPluginProvider = (
core: CoreStart,
plugins: ObservabilityLogExplorerStartDeps,
pluginStart: ObservabilityLogExplorerPluginStart,
appParams: ObservabilityLogExplorerAppMountParameters
plugins: ObservabilityLogsExplorerStartDeps,
pluginStart: ObservabilityLogsExplorerPluginStart,
appParams: ObservabilityLogsExplorerAppMountParameters
) => {
const { Provider } = useMemo(
() => createKibanaContextForPlugin(core, plugins, pluginStart, appParams),

View file

@ -7,7 +7,7 @@
import { schema, offeringBasedSchema } from '@kbn/config-schema';
import { PluginConfigDescriptor } from '@kbn/core/server';
import { ObservabilityLogExplorerConfig } from '../common/plugin_config';
import { ObservabilityLogsExplorerConfig } from '../common/plugin_config';
export const configSchema = schema.object({
enabled: schema.boolean({ defaultValue: true }),
@ -23,7 +23,7 @@ export const configSchema = schema.object({
}),
});
export const config: PluginConfigDescriptor<ObservabilityLogExplorerConfig> = {
export const config: PluginConfigDescriptor<ObservabilityLogsExplorerConfig> = {
schema: configSchema,
deprecations: ({ renameFromRoot }) => [
renameFromRoot(

View file

@ -8,6 +8,6 @@
export { config } from './config';
export const plugin = async () => {
const { ObservabilityLogExplorerServerPlugin } = await import('./plugin');
return new ObservabilityLogExplorerServerPlugin();
const { ObservabilityLogsExplorerServerPlugin } = await import('./plugin');
return new ObservabilityLogsExplorerServerPlugin();
};

View file

@ -7,7 +7,7 @@
import { Plugin } from '@kbn/core/server';
export class ObservabilityLogExplorerServerPlugin implements Plugin {
export class ObservabilityLogsExplorerServerPlugin implements Plugin {
setup() {}
start() {}