Skip to content

Commit

Permalink
[embeddable rebuild] log stream react embeddable (#184247)
Browse files Browse the repository at this point in the history
PR migrates log stream embeddable from the legacy class based system.

### test instructions
1. Run kibana on a system with o11y data and log streams
2. Create a new dashboard, click "Add panel" => "Log stream"
3. Verify panel behavior has not changed with legacy embeddable
4. Click panel context menu and select "Settings"
5. Set custom title, description and time range. Verify behavior has not
changed with legacy embeddable
6. Import dashboard with log stream panel. Verify behavior has not
changed with legacy embeddable

---------

Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
  • Loading branch information
nreese and kibanamachine committed Jun 7, 2024
1 parent 257ef7f commit 1a0b93a
Show file tree
Hide file tree
Showing 8 changed files with 203 additions and 197 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
await PageObjects.dashboard.clickNewDashboard();
await PageObjects.dashboard.switchToEditMode();
await dashboardAddPanel.clickEditorMenuButton();
await dashboardAddPanel.clickAddNewEmbeddableLink('LOG_STREAM_EMBEDDABLE');
await dashboardAddPanel.clickAddNewPanelFromUIActionLink('Log stream');
await dashboardAddPanel.expectEditorMenuClosed();
});

Expand Down
Original file line number Diff line number Diff line change
@@ -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 LOG_STREAM_EMBEDDABLE = 'LOG_STREAM_EMBEDDABLE';
export const ADD_LOG_STREAM_ACTION_ID = 'ADD_SEARCH_ACTION_ID';

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
/*
* 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 React, { FC, PropsWithChildren, useEffect, useMemo, useState } from 'react';
import { ReactEmbeddableFactory } from '@kbn/embeddable-plugin/public';
import {
initializeTimeRange,
initializeTitles,
useFetchContext,
} from '@kbn/presentation-publishing';
import { LogStream } from '@kbn/logs-shared-plugin/public';
import { AppMountParameters, CoreStart } from '@kbn/core/public';
import { EuiThemeProvider } from '@kbn/kibana-react-plugin/common';
import { Query } from '@kbn/es-query';
import { KibanaRenderContextProvider } from '@kbn/react-kibana-context-render';
import type { LogStreamApi, LogStreamSerializedState, Services } from './types';
import { datemathToEpochMillis } from '../../utils/datemath';
import { LOG_STREAM_EMBEDDABLE } from './constants';
import { useKibanaContextForPluginProvider } from '../../hooks/use_kibana';
import { InfraClientStartDeps, InfraClientStartExports } from '../../types';

export function getLogStreamEmbeddableFactory(services: Services) {
const factory: ReactEmbeddableFactory<LogStreamSerializedState, LogStreamApi> = {
type: LOG_STREAM_EMBEDDABLE,
deserializeState: (state) => state.rawState,
buildEmbeddable: async (state, buildApi) => {
const timeRangeContext = initializeTimeRange(state);
const { titlesApi, titleComparators, serializeTitles } = initializeTitles(state);

const api = buildApi(
{
...timeRangeContext.api,
...titlesApi,
serializeState: () => {
return {
rawState: {
...timeRangeContext.serialize(),
...serializeTitles(),
},
};
},
},
{
...timeRangeContext.comparators,
...titleComparators,
}
);

return {
api,
Component: () => {
const { filters, query, timeRange } = useFetchContext(api);
const { startTimestamp, endTimestamp } = useMemo(() => {
return {
startTimestamp: timeRange ? datemathToEpochMillis(timeRange.from) : undefined,
endTimestamp: timeRange ? datemathToEpochMillis(timeRange.to, 'up') : undefined,
};
}, [timeRange]);

const [darkMode, setDarkMode] = useState(false);
useEffect(() => {
const subscription = services.coreStart.theme.theme$.subscribe((theme) => {
setDarkMode(theme.darkMode);
});
return () => subscription.unsubscribe();
}, []);

return !startTimestamp || !endTimestamp ? null : (
<LogStreamEmbeddableProviders
core={services.coreStart}
plugins={services.pluginDeps}
pluginStart={services.pluginStart}
theme$={services.coreStart.theme.theme$}
>
<EuiThemeProvider darkMode={darkMode}>
<div style={{ width: '100%' }}>
<LogStream
logView={{ type: 'log-view-reference', logViewId: 'default' }}
startTimestamp={startTimestamp}
endTimestamp={endTimestamp}
height="100%"
query={query as Query | undefined}
filters={filters}
/>
</div>
</EuiThemeProvider>
</LogStreamEmbeddableProviders>
);
},
};
},
};
return factory;
}

export interface LogStreamEmbeddableProvidersProps {
core: CoreStart;
pluginStart: InfraClientStartExports;
plugins: InfraClientStartDeps;
theme$: AppMountParameters['theme$'];
}

export const LogStreamEmbeddableProviders: FC<
PropsWithChildren<LogStreamEmbeddableProvidersProps>
> = ({ children, core, pluginStart, plugins }) => {
const KibanaContextProviderForPlugin = useKibanaContextForPluginProvider(
core,
plugins,
pluginStart
);

return (
<KibanaRenderContextProvider {...core}>
<KibanaContextProviderForPlugin services={{ ...core, ...plugins, ...pluginStart }}>
{children}
</KibanaContextProviderForPlugin>
</KibanaRenderContextProvider>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/*
* 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 { CoreStart } from '@kbn/core/public';
import { DefaultEmbeddableApi } from '@kbn/embeddable-plugin/public';
import { SerializedTimeRange, SerializedTitles } from '@kbn/presentation-publishing';
import { InfraClientStartDeps, InfraClientStartExports } from '../../types';

export type LogStreamSerializedState = SerializedTitles & SerializedTimeRange;

export type LogStreamApi = DefaultEmbeddableApi<LogStreamSerializedState>;

export interface Services {
coreStart: CoreStart;
pluginDeps: InfraClientStartDeps;
pluginStart: InfraClientStartExports;
}
Loading

0 comments on commit 1a0b93a

Please sign in to comment.