diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS
index 12473d747c01..0a2b260b39da 100644
--- a/.github/CODEOWNERS
+++ b/.github/CODEOWNERS
@@ -547,6 +547,7 @@ src/platform/packages/shared/kbn-ui-theme @elastic/kibana-operations
src/platform/packages/shared/kbn-unified-data-table @elastic/kibana-data-discovery @elastic/security-threat-hunting-investigations
src/platform/packages/shared/kbn-unified-doc-viewer @elastic/kibana-data-discovery
src/platform/packages/shared/kbn-unified-field-list @elastic/kibana-data-discovery
+src/platform/packages/shared/kbn-unified-histogram @elastic/kibana-data-discovery
src/platform/packages/shared/kbn-unified-tabs @elastic/kibana-data-discovery
src/platform/packages/shared/kbn-unsaved-changes-prompt @elastic/kibana-management
src/platform/packages/shared/kbn-use-tracked-promise @elastic/obs-ux-logs-team
@@ -703,7 +704,6 @@ src/platform/plugins/shared/telemetry_management_section @elastic/kibana-core
src/platform/plugins/shared/ui_actions @elastic/appex-sharedux
src/platform/plugins/shared/ui_actions_enhanced @elastic/appex-sharedux
src/platform/plugins/shared/unified_doc_viewer @elastic/kibana-data-discovery
-src/platform/plugins/shared/unified_histogram @elastic/kibana-data-discovery
src/platform/plugins/shared/unified_search @elastic/kibana-presentation
src/platform/plugins/shared/usage_collection @elastic/kibana-core
src/platform/plugins/shared/vis_types/timeseries @elastic/kibana-visualizations
diff --git a/.i18nrc.json b/.i18nrc.json
index 114ba0c3d492..f226dd1d5349 100644
--- a/.i18nrc.json
+++ b/.i18nrc.json
@@ -154,7 +154,7 @@
"unifiedDocViewer": ["src/platform/plugins/shared/unified_doc_viewer", "src/platform/packages/shared/kbn-unified-doc-viewer"],
"unifiedSearch": "src/platform/plugins/shared/unified_search",
"unifiedFieldList": "src/platform/packages/shared/kbn-unified-field-list",
- "unifiedHistogram": "src/platform/plugins/shared/unified_histogram",
+ "unifiedHistogram": "src/platform/packages/shared/kbn-unified-histogram",
"unifiedDataTable": "src/platform/packages/shared/kbn-unified-data-table",
"unifiedTabs": "src/platform/packages/shared/kbn-unified-tabs",
"dataGridInTableSearch": "src/platform/packages/shared/kbn-data-grid-in-table-search",
diff --git a/docs/extend/plugin-list.md b/docs/extend/plugin-list.md
index cedf4ff5f327..ea704a8602af 100644
--- a/docs/extend/plugin-list.md
+++ b/docs/extend/plugin-list.md
@@ -82,7 +82,6 @@ mapped_pages:
| [uiActions](uiactions-plugin.md) | UI Actions plugins provides API to manage *triggers* and *actions*. *Trigger* is an abstract description of user's intent to perform an action (like user clicking on a value inside chart). It allows us to do runtime binding between code from different plugins. For, example one such trigger is when somebody applies filters on dashboard; another one is when somebody opens a Dashboard panel context menu. *Actions* are pieces of code that execute in response to a trigger. For example, to the dashboard filtering trigger multiple actions can be attached. Once a user filters on the dashboard all possible actions are displayed to the user in a popup menu and the user has to chose one. In general this plugin provides: - Creating custom functionality (actions). - Creating custom user interaction events (triggers). - Attaching and detaching actions to triggers. - Emitting trigger events. - Executing actions attached to a given trigger. - Exposing a context menu for the user to choose the appropriate action when there are multiple actions attached to a single trigger. |
| [uiActionsEnhanced](https://github.com/elastic/kibana/blob/main/src/platform/plugins/shared/ui_actions_enhanced/README.md) | Registers commercially licensed generic actions like per panel time range and contains some code that supports drilldown work. |
| [unifiedDocViewer](https://github.com/elastic/kibana/blob/main/src/platform/plugins/shared/unified_doc_viewer/README.md) | This plugin contains services reliant on the plugin lifecycle for the unified doc viewer component (see @kbn/unified-doc-viewer). |
-| [unifiedHistogram](https://github.com/elastic/kibana/blob/main/src/platform/plugins/shared/unified_histogram/README.md) | Unified Histogram is a UX Building Block including a layout with a resizable histogram and a main display. It manages its own state and data fetching, and can easily be dropped into pages with minimal setup. |
| [unifiedSearch](https://github.com/elastic/kibana/blob/main/src/platform/plugins/shared/unified_search/README.md) | Contains all the components of Kibana's unified search experience. Specifically: |
| [urlForwarding](https://github.com/elastic/kibana/blob/main/src/platform/plugins/private/url_forwarding/README.md) | This plugins contains helpers to redirect legacy URLs. It can be used to forward old URLs to their new counterparts. |
| [usageCollection](https://github.com/elastic/kibana/blob/main/src/platform/plugins/shared/usage_collection/README.mdx) | The Usage Collection Service defines a set of APIs for other plugins to report the usage of their features. At the same time, it provides necessary the APIs for other services (i.e.: telemetry, monitoring, ...) to consume that usage data. |
diff --git a/package.json b/package.json
index bed213520dcc..62abe21d18cd 100644
--- a/package.json
+++ b/package.json
@@ -998,7 +998,7 @@
"@kbn/unified-doc-viewer-plugin": "link:src/platform/plugins/shared/unified_doc_viewer",
"@kbn/unified-field-list": "link:src/platform/packages/shared/kbn-unified-field-list",
"@kbn/unified-field-list-examples-plugin": "link:examples/unified_field_list_examples",
- "@kbn/unified-histogram-plugin": "link:src/platform/plugins/shared/unified_histogram",
+ "@kbn/unified-histogram": "link:src/platform/packages/shared/kbn-unified-histogram",
"@kbn/unified-search-plugin": "link:src/platform/plugins/shared/unified_search",
"@kbn/unified-tabs": "link:src/platform/packages/shared/kbn-unified-tabs",
"@kbn/unified-tabs-examples-plugin": "link:examples/unified_tabs_examples",
diff --git a/packages/kbn-optimizer/limits.yml b/packages/kbn-optimizer/limits.yml
index 66ee2eb38b78..d617e1f32ff1 100644
--- a/packages/kbn-optimizer/limits.yml
+++ b/packages/kbn-optimizer/limits.yml
@@ -168,7 +168,6 @@ pageLoadAssetSize:
uiActions: 35121
uiActionsEnhanced: 38494
unifiedDocViewer: 25099
- unifiedHistogram: 19928
unifiedSearch: 23000
upgradeAssistant: 81241
uptime: 60000
diff --git a/src/platform/packages/shared/kbn-resizable-layout/src/panels_resizable.tsx b/src/platform/packages/shared/kbn-resizable-layout/src/panels_resizable.tsx
index dd0af5388f71..611278f92364 100644
--- a/src/platform/packages/shared/kbn-resizable-layout/src/panels_resizable.tsx
+++ b/src/platform/packages/shared/kbn-resizable-layout/src/panels_resizable.tsx
@@ -17,7 +17,7 @@ import {
import type { ResizeTrigger } from '@elastic/eui/src/components/resizable_container/types';
import { css } from '@emotion/react';
import { isEqual, round } from 'lodash';
-import type { ReactElement } from 'react';
+import type { ReactNode } from 'react';
import React, { useCallback, useEffect, useState } from 'react';
import { ResizableLayoutDirection } from '../types';
import { getContainerSize, percentToPixels, pixelsToPercent } from './utils';
@@ -47,8 +47,8 @@ export const PanelsResizable = ({
fixedPanelSizePct: number;
flexPanelSizePct: number;
};
- fixedPanel: ReactElement;
- flexPanel: ReactElement;
+ fixedPanel: ReactNode;
+ flexPanel: ReactNode;
resizeButtonClassName?: string;
['data-test-subj']?: string;
onFixedPanelSizeChange?: (fixedPanelSize: number) => void;
diff --git a/src/platform/packages/shared/kbn-resizable-layout/src/panels_static.tsx b/src/platform/packages/shared/kbn-resizable-layout/src/panels_static.tsx
index 6b637495d663..309c7bc57ae6 100644
--- a/src/platform/packages/shared/kbn-resizable-layout/src/panels_static.tsx
+++ b/src/platform/packages/shared/kbn-resizable-layout/src/panels_static.tsx
@@ -9,7 +9,7 @@
import { EuiFlexGroup, EuiFlexItem } from '@elastic/eui';
import { css } from '@emotion/react';
-import type { ReactElement } from 'react';
+import type { ReactNode } from 'react';
import React from 'react';
import { ResizableLayoutDirection } from '../types';
@@ -23,8 +23,8 @@ export const PanelsStatic = ({
className?: string;
direction: ResizableLayoutDirection;
hideFixedPanel?: boolean;
- fixedPanel: ReactElement;
- flexPanel: ReactElement;
+ fixedPanel: ReactNode;
+ flexPanel: ReactNode;
}) => {
// By default a flex item has overflow: visible, min-height: auto, and min-width: auto.
// This can cause the item to overflow the flexbox parent when its content is too large.
diff --git a/src/platform/packages/shared/kbn-resizable-layout/src/resizable_layout.tsx b/src/platform/packages/shared/kbn-resizable-layout/src/resizable_layout.tsx
index b216f6e883a3..62a766a2efe2 100644
--- a/src/platform/packages/shared/kbn-resizable-layout/src/resizable_layout.tsx
+++ b/src/platform/packages/shared/kbn-resizable-layout/src/resizable_layout.tsx
@@ -7,7 +7,7 @@
* License v3.0 only", or the "Server Side Public License, v 1".
*/
-import { ReactElement, useState } from 'react';
+import { ReactNode, useState } from 'react';
import React from 'react';
import { round } from 'lodash';
import { PanelsResizable } from './panels_resizable';
@@ -47,11 +47,11 @@ export interface ResizableLayoutProps {
/**
* The fixed panel
*/
- fixedPanel: ReactElement;
+ fixedPanel: ReactNode;
/**
* The flex panel
*/
- flexPanel: ReactElement;
+ flexPanel: ReactNode;
/**
* Class name for the resize button
*/
diff --git a/src/platform/packages/shared/kbn-scout/src/playwright/fixtures/test/performance/README.md b/src/platform/packages/shared/kbn-scout/src/playwright/fixtures/test/performance/README.md
index 9852e03c64a7..cb49df4789de 100644
--- a/src/platform/packages/shared/kbn-scout/src/playwright/fixtures/test/performance/README.md
+++ b/src/platform/packages/shared/kbn-scout/src/playwright/fixtures/test/performance/README.md
@@ -72,7 +72,6 @@ test.describe(
'kbn-ui-shared-deps-npm',
'lens',
'maps',
- 'unifiedHistogram',
'unifiedSearch',
]);
// Validate individual plugin bundle sizes
diff --git a/src/platform/packages/shared/kbn-unified-histogram/README.md b/src/platform/packages/shared/kbn-unified-histogram/README.md
new file mode 100644
index 000000000000..b5f531f2de96
--- /dev/null
+++ b/src/platform/packages/shared/kbn-unified-histogram/README.md
@@ -0,0 +1,3 @@
+# @kbn/unified-histogram
+
+Components for the Discover histogram chart
diff --git a/src/platform/plugins/shared/unified_histogram/public/__mocks__/data_view.ts b/src/platform/packages/shared/kbn-unified-histogram/__mocks__/data_view.ts
similarity index 100%
rename from src/platform/plugins/shared/unified_histogram/public/__mocks__/data_view.ts
rename to src/platform/packages/shared/kbn-unified-histogram/__mocks__/data_view.ts
diff --git a/src/platform/plugins/shared/unified_histogram/public/__mocks__/data_view_with_timefield.ts b/src/platform/packages/shared/kbn-unified-histogram/__mocks__/data_view_with_timefield.ts
similarity index 100%
rename from src/platform/plugins/shared/unified_histogram/public/__mocks__/data_view_with_timefield.ts
rename to src/platform/packages/shared/kbn-unified-histogram/__mocks__/data_view_with_timefield.ts
diff --git a/src/platform/plugins/shared/unified_histogram/public/__mocks__/lens_adapters.ts b/src/platform/packages/shared/kbn-unified-histogram/__mocks__/lens_adapters.ts
similarity index 100%
rename from src/platform/plugins/shared/unified_histogram/public/__mocks__/lens_adapters.ts
rename to src/platform/packages/shared/kbn-unified-histogram/__mocks__/lens_adapters.ts
diff --git a/src/platform/plugins/shared/unified_histogram/public/__mocks__/lens_vis.ts b/src/platform/packages/shared/kbn-unified-histogram/__mocks__/lens_vis.ts
similarity index 100%
rename from src/platform/plugins/shared/unified_histogram/public/__mocks__/lens_vis.ts
rename to src/platform/packages/shared/kbn-unified-histogram/__mocks__/lens_vis.ts
diff --git a/src/platform/plugins/shared/unified_histogram/public/__mocks__/services.tsx b/src/platform/packages/shared/kbn-unified-histogram/__mocks__/services.tsx
similarity index 100%
rename from src/platform/plugins/shared/unified_histogram/public/__mocks__/services.tsx
rename to src/platform/packages/shared/kbn-unified-histogram/__mocks__/services.tsx
diff --git a/src/platform/plugins/shared/unified_histogram/public/__mocks__/suggestions.ts b/src/platform/packages/shared/kbn-unified-histogram/__mocks__/suggestions.ts
similarity index 100%
rename from src/platform/plugins/shared/unified_histogram/public/__mocks__/suggestions.ts
rename to src/platform/packages/shared/kbn-unified-histogram/__mocks__/suggestions.ts
diff --git a/src/platform/plugins/shared/unified_histogram/public/__mocks__/table.ts b/src/platform/packages/shared/kbn-unified-histogram/__mocks__/table.ts
similarity index 100%
rename from src/platform/plugins/shared/unified_histogram/public/__mocks__/table.ts
rename to src/platform/packages/shared/kbn-unified-histogram/__mocks__/table.ts
diff --git a/src/platform/plugins/shared/unified_histogram/public/chart/breakdown_field_selector.test.tsx b/src/platform/packages/shared/kbn-unified-histogram/components/chart/breakdown_field_selector.test.tsx
similarity index 97%
rename from src/platform/plugins/shared/unified_histogram/public/chart/breakdown_field_selector.test.tsx
rename to src/platform/packages/shared/kbn-unified-histogram/components/chart/breakdown_field_selector.test.tsx
index 4342c00c9885..42c9c0c7d776 100644
--- a/src/platform/plugins/shared/unified_histogram/public/chart/breakdown_field_selector.test.tsx
+++ b/src/platform/packages/shared/kbn-unified-histogram/components/chart/breakdown_field_selector.test.tsx
@@ -12,8 +12,8 @@ import React from 'react';
import type { DatatableColumn } from '@kbn/expressions-plugin/common';
import { convertDatatableColumnToDataViewFieldSpec } from '@kbn/data-view-utils';
import { DataViewField } from '@kbn/data-views-plugin/common';
-import { UnifiedHistogramBreakdownContext } from '../types';
-import { dataViewWithTimefieldMock } from '../__mocks__/data_view_with_timefield';
+import { UnifiedHistogramBreakdownContext } from '../../types';
+import { dataViewWithTimefieldMock } from '../../__mocks__/data_view_with_timefield';
import { BreakdownFieldSelector } from './breakdown_field_selector';
describe('BreakdownFieldSelector', () => {
diff --git a/src/platform/plugins/shared/unified_histogram/public/chart/breakdown_field_selector.tsx b/src/platform/packages/shared/kbn-unified-histogram/components/chart/breakdown_field_selector.tsx
similarity index 98%
rename from src/platform/plugins/shared/unified_histogram/public/chart/breakdown_field_selector.tsx
rename to src/platform/packages/shared/kbn-unified-histogram/components/chart/breakdown_field_selector.tsx
index 418892bd5434..8212e836b19f 100644
--- a/src/platform/plugins/shared/unified_histogram/public/chart/breakdown_field_selector.tsx
+++ b/src/platform/packages/shared/kbn-unified-histogram/components/chart/breakdown_field_selector.tsx
@@ -21,7 +21,7 @@ import { type DataView, DataViewField } from '@kbn/data-views-plugin/common';
import type { DatatableColumn } from '@kbn/expressions-plugin/common';
import { convertDatatableColumnToDataViewFieldSpec } from '@kbn/data-view-utils';
import { i18n } from '@kbn/i18n';
-import { UnifiedHistogramBreakdownContext } from '../types';
+import { UnifiedHistogramBreakdownContext } from '../../types';
import {
ToolbarSelector,
ToolbarSelectorProps,
diff --git a/src/platform/plugins/shared/unified_histogram/public/chart/chart.test.tsx b/src/platform/packages/shared/kbn-unified-histogram/components/chart/chart.test.tsx
similarity index 93%
rename from src/platform/plugins/shared/unified_histogram/public/chart/chart.test.tsx
rename to src/platform/packages/shared/kbn-unified-histogram/components/chart/chart.test.tsx
index a6e5e9b1ad75..e2fbdaa48408 100644
--- a/src/platform/plugins/shared/unified_histogram/public/chart/chart.test.tsx
+++ b/src/platform/packages/shared/kbn-unified-histogram/components/chart/chart.test.tsx
@@ -13,18 +13,18 @@ import { mountWithIntl } from '@kbn/test-jest-helpers';
import type { Capabilities } from '@kbn/core/public';
import type { DataView } from '@kbn/data-views-plugin/public';
import type { Suggestion } from '@kbn/lens-plugin/public';
-import type { UnifiedHistogramFetchStatus } from '../types';
-import { Chart, type ChartProps } from './chart';
+import type { UnifiedHistogramFetchStatus } from '../../types';
+import { UnifiedHistogramChart, type UnifiedHistogramChartProps } from './chart';
import type { ReactWrapper } from 'enzyme';
-import { unifiedHistogramServicesMock } from '../__mocks__/services';
-import { getLensVisMock } from '../__mocks__/lens_vis';
+import { unifiedHistogramServicesMock } from '../../__mocks__/services';
+import { getLensVisMock } from '../../__mocks__/lens_vis';
import { searchSourceInstanceMock } from '@kbn/data-plugin/common/search/search_source/mocks';
import { Subject, of } from 'rxjs';
-import { dataViewWithTimefieldMock } from '../__mocks__/data_view_with_timefield';
-import { dataViewMock } from '../__mocks__/data_view';
+import { dataViewWithTimefieldMock } from '../../__mocks__/data_view_with_timefield';
+import { dataViewMock } from '../../__mocks__/data_view';
import { BreakdownFieldSelector } from './breakdown_field_selector';
-import { checkChartAvailability } from './check_chart_availability';
-import { allSuggestionsMock } from '../__mocks__/suggestions';
+import { checkChartAvailability } from './utils/check_chart_availability';
+import { allSuggestionsMock } from '../../__mocks__/suggestions';
let mockUseEditVisualization: jest.Mock | undefined = jest.fn();
@@ -38,7 +38,6 @@ async function mountComponent({
noHits,
noBreakdown,
chartHidden = false,
- appendHistogram,
dataView = dataViewWithTimefieldMock,
allSuggestions,
isPlainRecord,
@@ -51,7 +50,6 @@ async function mountComponent({
noHits?: boolean;
noBreakdown?: boolean;
chartHidden?: boolean;
- appendHistogram?: ReactElement;
dataView?: DataView;
allSuggestions?: Suggestion[];
isPlainRecord?: boolean;
@@ -114,7 +112,7 @@ async function mountComponent({
})
).lensService;
- const props: ChartProps = {
+ const props: UnifiedHistogramChartProps = {
lensVisService,
dataView,
requestParams,
@@ -129,7 +127,6 @@ async function mountComponent({
breakdown: noBreakdown ? undefined : { field: undefined },
isChartLoading: Boolean(isChartLoading),
isPlainRecord,
- appendHistogram,
onChartHiddenChange: jest.fn(),
onTimeIntervalChange: jest.fn(),
withDefaultActions: undefined,
@@ -140,7 +137,7 @@ async function mountComponent({
let instance: ReactWrapper = {} as ReactWrapper;
await act(async () => {
- instance = mountWithIntl();
+ instance = mountWithIntl();
// wait for initial async loading to complete
await new Promise((r) => setTimeout(r, 0));
props.input$?.next({ type: 'fetch' });
@@ -339,12 +336,6 @@ describe('Chart', () => {
expect(mockUseEditVisualization).toHaveBeenCalled();
});
- it('should render the element passed to appendHistogram', async () => {
- const appendHistogram =
;
- const component = await mountComponent({ appendHistogram });
- expect(component.find('[data-test-subj="appendHistogram"]').exists()).toBeTruthy();
- });
-
it('should not render chart if data view is not time based', async () => {
const component = await mountComponent({ dataView: dataViewMock });
expect(component.find('[data-test-subj="unifiedHistogramChart"]').exists()).toBeFalsy();
diff --git a/src/platform/plugins/shared/unified_histogram/public/chart/chart.tsx b/src/platform/packages/shared/kbn-unified-histogram/components/chart/chart.tsx
similarity index 93%
rename from src/platform/plugins/shared/unified_histogram/public/chart/chart.tsx
rename to src/platform/packages/shared/kbn-unified-histogram/components/chart/chart.tsx
index 47834d1d41f6..bc662386d131 100644
--- a/src/platform/plugins/shared/unified_histogram/public/chart/chart.tsx
+++ b/src/platform/packages/shared/kbn-unified-histogram/components/chart/chart.tsx
@@ -11,7 +11,7 @@ import React, { memo, ReactElement, useCallback, useEffect, useMemo, useState }
import { Subject } from 'rxjs';
import useObservable from 'react-use/lib/useObservable';
import { IconButtonGroup, type IconButtonGroupProps } from '@kbn/shared-ux-button-toolbar';
-import { EuiFlexGroup, EuiFlexItem, EuiProgress, EuiDelayRender } from '@elastic/eui';
+import { EuiFlexGroup, EuiFlexItem, EuiProgress, EuiDelayRender, EuiSpacer } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import type {
EmbeddableComponentProps,
@@ -26,7 +26,7 @@ import type {
import type { DataView, DataViewField } from '@kbn/data-views-plugin/public';
import type { TimeRange } from '@kbn/es-query';
import { PublishingSubject } from '@kbn/presentation-publishing';
-import { RequestStatus } from '@kbn/inspector-plugin/public';
+import type { RequestStatus } from '@kbn/inspector-plugin/public';
import { IKibanaSearchResponse } from '@kbn/search-types';
import type { estypes } from '@elastic/elasticsearch';
import { Histogram } from './histogram';
@@ -42,8 +42,8 @@ import {
UnifiedHistogramRequestContext,
UnifiedHistogramServices,
UnifiedHistogramBucketInterval,
-} from '../types';
-import { UnifiedHistogramSuggestionType } from '../types';
+} from '../../types';
+import { UnifiedHistogramSuggestionType } from '../../types';
import { BreakdownFieldSelector } from './breakdown_field_selector';
import { TimeIntervalSelector } from './time_interval_selector';
import { useTotalHits } from './hooks/use_total_hits';
@@ -52,18 +52,17 @@ import { useChartActions } from './hooks/use_chart_actions';
import { ChartConfigPanel } from './chart_config_panel';
import { useFetch } from './hooks/use_fetch';
import { useEditVisualization } from './hooks/use_edit_visualization';
-import { LensVisService } from '../services/lens_vis_service';
-import type { UseRequestParamsResult } from '../hooks/use_request_params';
-import { removeTablesFromLensAttributes } from '../utils/lens_vis_from_table';
+import { LensVisService } from '../../services/lens_vis_service';
+import type { UseRequestParamsResult } from '../../hooks/use_request_params';
+import { removeTablesFromLensAttributes } from '../../utils/lens_vis_from_table';
import { useLensProps } from './hooks/use_lens_props';
-import { useStableCallback } from '../hooks/use_stable_callback';
+import { useStableCallback } from '../../hooks/use_stable_callback';
import { buildBucketInterval } from './utils/build_bucket_interval';
-export interface ChartProps {
+export interface UnifiedHistogramChartProps {
abortController?: AbortController;
isChartAvailable: boolean;
hiddenPanel?: boolean;
- className?: string;
services: UnifiedHistogramServices;
dataView: DataView;
requestParams: UseRequestParamsResult;
@@ -75,7 +74,6 @@ export interface ChartProps {
chart?: UnifiedHistogramChartContext;
breakdown?: UnifiedHistogramBreakdownContext;
renderCustomChartToggleActions?: () => ReactElement | undefined;
- appendHistogram?: ReactElement;
disableTriggers?: LensEmbeddableInput['disableTriggers'];
disabledActions?: LensEmbeddableInput['disabledActions'];
input$?: UnifiedHistogramInput$;
@@ -89,15 +87,15 @@ export interface ChartProps {
onChartLoad?: (event: UnifiedHistogramChartLoadEvent) => void;
onFilter?: LensEmbeddableInput['onFilter'];
onBrushEnd?: LensEmbeddableInput['onBrushEnd'];
- withDefaultActions: EmbeddableComponentProps['withDefaultActions'];
+ withDefaultActions?: EmbeddableComponentProps['withDefaultActions'];
columns?: DatatableColumn[];
}
+const RequestStatusError: typeof RequestStatus.ERROR = 2;
const HistogramMemoized = memo(Histogram);
-export function Chart({
+export function UnifiedHistogramChart({
isChartAvailable,
- className,
services,
dataView,
requestParams,
@@ -109,9 +107,6 @@ export function Chart({
lensVisService,
isPlainRecord,
renderCustomChartToggleActions,
- appendHistogram,
- disableTriggers,
- disabledActions,
input$: originalInput$,
lensAdapters,
dataLoading$,
@@ -121,12 +116,9 @@ export function Chart({
onBreakdownFieldChange,
onTotalHitsChange,
onChartLoad,
- onFilter,
- onBrushEnd,
- withDefaultActions,
- abortController,
columns,
-}: ChartProps) {
+ ...histogramProps
+}: UnifiedHistogramChartProps) {
const lensVisServiceCurrentSuggestionContext = useObservable(
lensVisService.currentSuggestionContext$
);
@@ -177,7 +169,7 @@ export function Chart({
dataLoadingSubject$?: PublishingSubject
) => {
const lensRequest = adapters?.requests?.getRequests()[0];
- const requestFailed = lensRequest?.status === RequestStatus.ERROR;
+ const requestFailed = lensRequest?.status === RequestStatusError;
const json = lensRequest?.response?.json as
| IKibanaSearchResponse
| undefined;
@@ -315,7 +307,7 @@ export function Chart({
return (
)}
- {appendHistogram}
+
)}
{canSaveVisualization && isSaveModalVisible && visContext.attributes && (
diff --git a/src/platform/plugins/shared/unified_histogram/public/chart/chart_config_panel.test.tsx b/src/platform/packages/shared/kbn-unified-histogram/components/chart/chart_config_panel.test.tsx
similarity index 87%
rename from src/platform/plugins/shared/unified_histogram/public/chart/chart_config_panel.test.tsx
rename to src/platform/packages/shared/kbn-unified-histogram/components/chart/chart_config_panel.test.tsx
index 95391efc0900..56efd7cd90f1 100644
--- a/src/platform/plugins/shared/unified_histogram/public/chart/chart_config_panel.test.tsx
+++ b/src/platform/packages/shared/kbn-unified-histogram/components/chart/chart_config_panel.test.tsx
@@ -12,13 +12,13 @@ import type { TypedLensByValueInput } from '@kbn/lens-plugin/public';
import { render } from '@testing-library/react';
import { act } from 'react-dom/test-utils';
import { setTimeout } from 'timers/promises';
-import { dataViewWithTimefieldMock } from '../__mocks__/data_view_with_timefield';
-import { unifiedHistogramServicesMock } from '../__mocks__/services';
-import { currentSuggestionMock } from '../__mocks__/suggestions';
-import { lensAdaptersMock } from '../__mocks__/lens_adapters';
+import { dataViewWithTimefieldMock } from '../../__mocks__/data_view_with_timefield';
+import { unifiedHistogramServicesMock } from '../../__mocks__/services';
+import { currentSuggestionMock } from '../../__mocks__/suggestions';
+import { lensAdaptersMock } from '../../__mocks__/lens_adapters';
import { ChartConfigPanel } from './chart_config_panel';
-import type { UnifiedHistogramVisContext } from '../types';
-import { UnifiedHistogramSuggestionType } from '../types';
+import type { UnifiedHistogramVisContext } from '../../types';
+import { UnifiedHistogramSuggestionType } from '../../types';
describe('ChartConfigPanel', () => {
it('should return a jsx element to edit the visualization', async () => {
diff --git a/src/platform/plugins/shared/unified_histogram/public/chart/chart_config_panel.tsx b/src/platform/packages/shared/kbn-unified-histogram/components/chart/chart_config_panel.tsx
similarity index 96%
rename from src/platform/plugins/shared/unified_histogram/public/chart/chart_config_panel.tsx
rename to src/platform/packages/shared/kbn-unified-histogram/components/chart/chart_config_panel.tsx
index a7a82cff8604..19bf1b8bb4e5 100644
--- a/src/platform/plugins/shared/unified_histogram/public/chart/chart_config_panel.tsx
+++ b/src/platform/packages/shared/kbn-unified-histogram/components/chart/chart_config_panel.tsx
@@ -12,9 +12,9 @@ import type { AggregateQuery, Query } from '@kbn/es-query';
import { isEqual, isObject } from 'lodash';
import type { LensEmbeddableOutput, Suggestion } from '@kbn/lens-plugin/public';
import type { Datatable } from '@kbn/expressions-plugin/common';
-import { EditLensConfigPanelComponent } from '@kbn/lens-plugin/public/plugin';
+import type { EditLensConfigPanelComponent } from '@kbn/lens-plugin/public/plugin';
import { DiscoverFlyouts, dismissAllFlyoutsExceptFor } from '@kbn/discover-utils';
-import { deriveLensSuggestionFromLensAttributes } from '../utils/external_vis_context';
+import { deriveLensSuggestionFromLensAttributes } from '../../utils/external_vis_context';
import {
UnifiedHistogramChartLoadEvent,
@@ -22,7 +22,7 @@ import {
UnifiedHistogramSuggestionContext,
UnifiedHistogramSuggestionType,
UnifiedHistogramVisContext,
-} from '../types';
+} from '../../types';
export function ChartConfigPanel({
services,
diff --git a/src/platform/plugins/shared/unified_histogram/public/chart/histogram.test.tsx b/src/platform/packages/shared/kbn-unified-histogram/components/chart/histogram.test.tsx
similarity index 97%
rename from src/platform/plugins/shared/unified_histogram/public/chart/histogram.test.tsx
rename to src/platform/packages/shared/kbn-unified-histogram/components/chart/histogram.test.tsx
index be213b08a1ac..7d6e5457ff01 100644
--- a/src/platform/plugins/shared/unified_histogram/public/chart/histogram.test.tsx
+++ b/src/platform/packages/shared/kbn-unified-histogram/components/chart/histogram.test.tsx
@@ -11,11 +11,11 @@ import { mountWithIntl } from '@kbn/test-jest-helpers';
import { Histogram, HistogramProps } from './histogram';
import React from 'react';
import { BehaviorSubject, Subject } from 'rxjs';
-import { unifiedHistogramServicesMock } from '../__mocks__/services';
-import { getLensVisMock } from '../__mocks__/lens_vis';
-import { dataViewWithTimefieldMock } from '../__mocks__/data_view_with_timefield';
+import { unifiedHistogramServicesMock } from '../../__mocks__/services';
+import { getLensVisMock } from '../../__mocks__/lens_vis';
+import { dataViewWithTimefieldMock } from '../../__mocks__/data_view_with_timefield';
import { createDefaultInspectorAdapters } from '@kbn/expressions-plugin/common';
-import { UnifiedHistogramInput$ } from '../types';
+import { UnifiedHistogramInput$ } from '../../types';
import { act } from 'react-dom/test-utils';
import { RequestStatus } from '@kbn/inspector-plugin/public';
import { getLensProps, useLensProps } from './hooks/use_lens_props';
diff --git a/src/platform/plugins/shared/unified_histogram/public/chart/histogram.tsx b/src/platform/packages/shared/kbn-unified-histogram/components/chart/histogram.tsx
similarity index 97%
rename from src/platform/plugins/shared/unified_histogram/public/chart/histogram.tsx
rename to src/platform/packages/shared/kbn-unified-histogram/components/chart/histogram.tsx
index ad35f6141b4b..4804e9727c4e 100644
--- a/src/platform/plugins/shared/unified_histogram/public/chart/histogram.tsx
+++ b/src/platform/packages/shared/kbn-unified-histogram/components/chart/histogram.tsx
@@ -18,7 +18,7 @@ import type {
UnifiedHistogramChartContext,
UnifiedHistogramServices,
UnifiedHistogramVisContext,
-} from '../types';
+} from '../../types';
import { useTimeRange } from './hooks/use_time_range';
import type { LensProps } from './hooks/use_lens_props';
@@ -37,7 +37,7 @@ export interface HistogramProps {
disabledActions?: LensEmbeddableInput['disabledActions'];
onFilter?: LensEmbeddableInput['onFilter'];
onBrushEnd?: LensEmbeddableInput['onBrushEnd'];
- withDefaultActions: EmbeddableComponentProps['withDefaultActions'];
+ withDefaultActions?: EmbeddableComponentProps['withDefaultActions'];
}
export function Histogram({
diff --git a/src/platform/plugins/shared/unified_histogram/public/chart/hooks/use_chart_actions.test.ts b/src/platform/packages/shared/kbn-unified-histogram/components/chart/hooks/use_chart_actions.test.ts
similarity index 96%
rename from src/platform/plugins/shared/unified_histogram/public/chart/hooks/use_chart_actions.test.ts
rename to src/platform/packages/shared/kbn-unified-histogram/components/chart/hooks/use_chart_actions.test.ts
index 94c7c88005f7..7ad7c7baea5d 100644
--- a/src/platform/plugins/shared/unified_histogram/public/chart/hooks/use_chart_actions.test.ts
+++ b/src/platform/packages/shared/kbn-unified-histogram/components/chart/hooks/use_chart_actions.test.ts
@@ -8,7 +8,7 @@
*/
import { act, renderHook } from '@testing-library/react';
-import { UnifiedHistogramChartContext } from '../../types';
+import { UnifiedHistogramChartContext } from '../../../types';
import { useChartActions } from './use_chart_actions';
describe('useChartActions', () => {
diff --git a/src/platform/plugins/shared/unified_histogram/public/chart/hooks/use_chart_actions.ts b/src/platform/packages/shared/kbn-unified-histogram/components/chart/hooks/use_chart_actions.ts
similarity index 94%
rename from src/platform/plugins/shared/unified_histogram/public/chart/hooks/use_chart_actions.ts
rename to src/platform/packages/shared/kbn-unified-histogram/components/chart/hooks/use_chart_actions.ts
index fbf4aecfe28a..0082f8123df0 100644
--- a/src/platform/plugins/shared/unified_histogram/public/chart/hooks/use_chart_actions.ts
+++ b/src/platform/packages/shared/kbn-unified-histogram/components/chart/hooks/use_chart_actions.ts
@@ -8,7 +8,7 @@
*/
import { useCallback, useEffect, useRef } from 'react';
-import type { UnifiedHistogramChartContext } from '../../types';
+import type { UnifiedHistogramChartContext } from '../../../types';
export const useChartActions = ({
chart,
diff --git a/src/platform/plugins/shared/unified_histogram/public/chart/hooks/use_chart_styles.tsx b/src/platform/packages/shared/kbn-unified-histogram/components/chart/hooks/use_chart_styles.tsx
similarity index 100%
rename from src/platform/plugins/shared/unified_histogram/public/chart/hooks/use_chart_styles.tsx
rename to src/platform/packages/shared/kbn-unified-histogram/components/chart/hooks/use_chart_styles.tsx
diff --git a/src/platform/plugins/shared/unified_histogram/public/chart/hooks/use_edit_visualization.test.ts b/src/platform/packages/shared/kbn-unified-histogram/components/chart/hooks/use_edit_visualization.test.ts
similarity index 95%
rename from src/platform/plugins/shared/unified_histogram/public/chart/hooks/use_edit_visualization.test.ts
rename to src/platform/packages/shared/kbn-unified-histogram/components/chart/hooks/use_edit_visualization.test.ts
index 626950e53561..f1e5a97f79c9 100644
--- a/src/platform/plugins/shared/unified_histogram/public/chart/hooks/use_edit_visualization.test.ts
+++ b/src/platform/packages/shared/kbn-unified-histogram/components/chart/hooks/use_edit_visualization.test.ts
@@ -10,9 +10,9 @@
import type { DataView } from '@kbn/data-views-plugin/common';
import type { TypedLensByValueInput } from '@kbn/lens-plugin/public';
import { waitFor, renderHook } from '@testing-library/react';
-import { dataViewMock } from '../../__mocks__/data_view';
-import { dataViewWithTimefieldMock } from '../../__mocks__/data_view_with_timefield';
-import { unifiedHistogramServicesMock } from '../../__mocks__/services';
+import { dataViewMock } from '../../../__mocks__/data_view';
+import { dataViewWithTimefieldMock } from '../../../__mocks__/data_view_with_timefield';
+import { unifiedHistogramServicesMock } from '../../../__mocks__/services';
import { useEditVisualization } from './use_edit_visualization';
const getTriggerCompatibleActions = unifiedHistogramServicesMock.uiActions
diff --git a/src/platform/plugins/shared/unified_histogram/public/chart/hooks/use_edit_visualization.ts b/src/platform/packages/shared/kbn-unified-histogram/components/chart/hooks/use_edit_visualization.ts
similarity index 97%
rename from src/platform/plugins/shared/unified_histogram/public/chart/hooks/use_edit_visualization.ts
rename to src/platform/packages/shared/kbn-unified-histogram/components/chart/hooks/use_edit_visualization.ts
index 3a88f51be01e..4a0cf380113d 100644
--- a/src/platform/plugins/shared/unified_histogram/public/chart/hooks/use_edit_visualization.ts
+++ b/src/platform/packages/shared/kbn-unified-histogram/components/chart/hooks/use_edit_visualization.ts
@@ -12,7 +12,7 @@ import type { TimeRange } from '@kbn/es-query';
import type { TypedLensByValueInput } from '@kbn/lens-plugin/public';
import type { VISUALIZE_FIELD_TRIGGER } from '@kbn/ui-actions-plugin/public';
import { useCallback, useEffect, useMemo, useState } from 'react';
-import type { UnifiedHistogramServices } from '../..';
+import type { UnifiedHistogramServices } from '../../..';
// Avoid taking a dependency on uiActionsPlugin just for this const
const visualizeFieldTrigger: typeof VISUALIZE_FIELD_TRIGGER = 'VISUALIZE_FIELD_TRIGGER';
diff --git a/src/platform/plugins/shared/unified_histogram/public/chart/hooks/use_fetch.test.ts b/src/platform/packages/shared/kbn-unified-histogram/components/chart/hooks/use_fetch.test.ts
similarity index 95%
rename from src/platform/plugins/shared/unified_histogram/public/chart/hooks/use_fetch.test.ts
rename to src/platform/packages/shared/kbn-unified-histogram/components/chart/hooks/use_fetch.test.ts
index d8be832908e0..6a667f2c4ab8 100644
--- a/src/platform/plugins/shared/unified_histogram/public/chart/hooks/use_fetch.test.ts
+++ b/src/platform/packages/shared/kbn-unified-histogram/components/chart/hooks/use_fetch.test.ts
@@ -9,7 +9,7 @@
import { useFetch } from './use_fetch';
import { renderHook } from '@testing-library/react';
-import { UnifiedHistogramInput$ } from '../../types';
+import { UnifiedHistogramInput$ } from '../../../types';
import { Subject } from 'rxjs';
describe('useFetch', () => {
diff --git a/src/platform/plugins/shared/unified_histogram/public/chart/hooks/use_fetch.ts b/src/platform/packages/shared/kbn-unified-histogram/components/chart/hooks/use_fetch.ts
similarity index 93%
rename from src/platform/plugins/shared/unified_histogram/public/chart/hooks/use_fetch.ts
rename to src/platform/packages/shared/kbn-unified-histogram/components/chart/hooks/use_fetch.ts
index e48d1026a9d3..e16902b83aed 100644
--- a/src/platform/plugins/shared/unified_histogram/public/chart/hooks/use_fetch.ts
+++ b/src/platform/packages/shared/kbn-unified-histogram/components/chart/hooks/use_fetch.ts
@@ -9,7 +9,7 @@
import { useMemo } from 'react';
import { filter, share, tap } from 'rxjs';
-import { UnifiedHistogramInput$ } from '../../types';
+import { UnifiedHistogramInput$ } from '../../../types';
export const useFetch = ({
input$,
diff --git a/src/platform/plugins/shared/unified_histogram/public/chart/hooks/use_lens_props.test.ts b/src/platform/packages/shared/kbn-unified-histogram/components/chart/hooks/use_lens_props.test.ts
similarity index 95%
rename from src/platform/plugins/shared/unified_histogram/public/chart/hooks/use_lens_props.test.ts
rename to src/platform/packages/shared/kbn-unified-histogram/components/chart/hooks/use_lens_props.test.ts
index 8ec349b7ee85..dbdbf3209cad 100644
--- a/src/platform/plugins/shared/unified_histogram/public/chart/hooks/use_lens_props.test.ts
+++ b/src/platform/packages/shared/kbn-unified-histogram/components/chart/hooks/use_lens_props.test.ts
@@ -9,9 +9,9 @@
import { act, renderHook } from '@testing-library/react';
import { Subject } from 'rxjs';
-import type { UnifiedHistogramInputMessage } from '../../types';
-import { dataViewWithTimefieldMock } from '../../__mocks__/data_view_with_timefield';
-import { getLensVisMock } from '../../__mocks__/lens_vis';
+import type { UnifiedHistogramInputMessage } from '../../../types';
+import { dataViewWithTimefieldMock } from '../../../__mocks__/data_view_with_timefield';
+import { getLensVisMock } from '../../../__mocks__/lens_vis';
import { getLensProps, useLensProps } from './use_lens_props';
describe('useLensProps', () => {
diff --git a/src/platform/plugins/shared/unified_histogram/public/chart/hooks/use_lens_props.ts b/src/platform/packages/shared/kbn-unified-histogram/components/chart/hooks/use_lens_props.ts
similarity index 96%
rename from src/platform/plugins/shared/unified_histogram/public/chart/hooks/use_lens_props.ts
rename to src/platform/packages/shared/kbn-unified-histogram/components/chart/hooks/use_lens_props.ts
index 3a3c20c51507..a307d6db4868 100644
--- a/src/platform/plugins/shared/unified_histogram/public/chart/hooks/use_lens_props.ts
+++ b/src/platform/packages/shared/kbn-unified-histogram/components/chart/hooks/use_lens_props.ts
@@ -16,8 +16,8 @@ import type {
UnifiedHistogramInputMessage,
UnifiedHistogramRequestContext,
UnifiedHistogramVisContext,
-} from '../../types';
-import { useStableCallback } from '../../hooks/use_stable_callback';
+} from '../../../types';
+import { useStableCallback } from '../../../hooks/use_stable_callback';
export type LensProps = Pick<
EmbeddableComponentProps,
diff --git a/src/platform/plugins/shared/unified_histogram/public/chart/hooks/use_time_range.test.tsx b/src/platform/packages/shared/kbn-unified-histogram/components/chart/hooks/use_time_range.test.tsx
similarity index 98%
rename from src/platform/plugins/shared/unified_histogram/public/chart/hooks/use_time_range.test.tsx
rename to src/platform/packages/shared/kbn-unified-histogram/components/chart/hooks/use_time_range.test.tsx
index 560105db09b1..0cdda5df59fd 100644
--- a/src/platform/plugins/shared/unified_histogram/public/chart/hooks/use_time_range.test.tsx
+++ b/src/platform/packages/shared/kbn-unified-histogram/components/chart/hooks/use_time_range.test.tsx
@@ -10,7 +10,7 @@
import { uiSettingsServiceMock } from '@kbn/core-ui-settings-browser-mocks';
import { TimeRange } from '@kbn/data-plugin/common';
import { renderHook } from '@testing-library/react';
-import { UnifiedHistogramBucketInterval } from '../../types';
+import { UnifiedHistogramBucketInterval } from '../../../types';
import { useTimeRange } from './use_time_range';
jest.mock('@kbn/datemath', () => ({
diff --git a/src/platform/plugins/shared/unified_histogram/public/chart/hooks/use_time_range.tsx b/src/platform/packages/shared/kbn-unified-histogram/components/chart/hooks/use_time_range.tsx
similarity index 98%
rename from src/platform/plugins/shared/unified_histogram/public/chart/hooks/use_time_range.tsx
rename to src/platform/packages/shared/kbn-unified-histogram/components/chart/hooks/use_time_range.tsx
index 9be364c46f76..12ce1374606e 100644
--- a/src/platform/plugins/shared/unified_histogram/public/chart/hooks/use_time_range.tsx
+++ b/src/platform/packages/shared/kbn-unified-histogram/components/chart/hooks/use_time_range.tsx
@@ -14,7 +14,7 @@ import { i18n } from '@kbn/i18n';
import React, { useCallback, useMemo } from 'react';
import dateMath from '@kbn/datemath';
import type { TimeRange } from '@kbn/data-plugin/common';
-import type { UnifiedHistogramBucketInterval } from '../../types';
+import type { UnifiedHistogramBucketInterval } from '../../../types';
export const useTimeRange = ({
uiSettings,
diff --git a/src/platform/plugins/shared/unified_histogram/public/chart/hooks/use_total_hits.test.ts b/src/platform/packages/shared/kbn-unified-histogram/components/chart/hooks/use_total_hits.test.ts
similarity index 98%
rename from src/platform/plugins/shared/unified_histogram/public/chart/hooks/use_total_hits.test.ts
rename to src/platform/packages/shared/kbn-unified-histogram/components/chart/hooks/use_total_hits.test.ts
index 9f7c1ef4c118..6223b800f588 100644
--- a/src/platform/plugins/shared/unified_histogram/public/chart/hooks/use_total_hits.test.ts
+++ b/src/platform/packages/shared/kbn-unified-histogram/components/chart/hooks/use_total_hits.test.ts
@@ -8,8 +8,8 @@
*/
import { Filter } from '@kbn/es-query';
-import { UnifiedHistogramFetchStatus, UnifiedHistogramInput$ } from '../../types';
-import { dataViewWithTimefieldMock } from '../../__mocks__/data_view_with_timefield';
+import { UnifiedHistogramFetchStatus, UnifiedHistogramInput$ } from '../../../types';
+import { dataViewWithTimefieldMock } from '../../../__mocks__/data_view_with_timefield';
import { useTotalHits } from './use_total_hits';
import { useEffect as mockUseEffect } from 'react';
import { dataPluginMock } from '@kbn/data-plugin/public/mocks';
diff --git a/src/platform/plugins/shared/unified_histogram/public/chart/hooks/use_total_hits.ts b/src/platform/packages/shared/kbn-unified-histogram/components/chart/hooks/use_total_hits.ts
similarity index 98%
rename from src/platform/plugins/shared/unified_histogram/public/chart/hooks/use_total_hits.ts
rename to src/platform/packages/shared/kbn-unified-histogram/components/chart/hooks/use_total_hits.ts
index 5f338c8500b3..6a0e1464c455 100644
--- a/src/platform/plugins/shared/unified_histogram/public/chart/hooks/use_total_hits.ts
+++ b/src/platform/packages/shared/kbn-unified-histogram/components/chart/hooks/use_total_hits.ts
@@ -19,8 +19,8 @@ import {
UnifiedHistogramInputMessage,
UnifiedHistogramRequestContext,
UnifiedHistogramServices,
-} from '../../types';
-import { useStableCallback } from '../../hooks/use_stable_callback';
+} from '../../../types';
+import { useStableCallback } from '../../../hooks/use_stable_callback';
export const useTotalHits = ({
services,
diff --git a/src/platform/plugins/shared/unified_histogram/public/plugin.ts b/src/platform/packages/shared/kbn-unified-histogram/components/chart/index.ts
similarity index 69%
rename from src/platform/plugins/shared/unified_histogram/public/plugin.ts
rename to src/platform/packages/shared/kbn-unified-histogram/components/chart/index.ts
index afb794d48c30..2ae9cec1b583 100644
--- a/src/platform/plugins/shared/unified_histogram/public/plugin.ts
+++ b/src/platform/packages/shared/kbn-unified-histogram/components/chart/index.ts
@@ -7,14 +7,5 @@
* License v3.0 only", or the "Server Side Public License, v 1".
*/
-import type { Plugin } from '@kbn/core/public';
-
-export class UnifiedHistogramPublicPlugin implements Plugin<{}, {}, object, {}> {
- public setup() {
- return {};
- }
-
- public start() {
- return {};
- }
-}
+export { UnifiedHistogramChart, type UnifiedHistogramChartProps } from './chart';
+export { checkChartAvailability } from './utils/check_chart_availability';
diff --git a/src/platform/plugins/shared/unified_histogram/public/chart/lazy.tsx b/src/platform/packages/shared/kbn-unified-histogram/components/chart/lazy.tsx
similarity index 100%
rename from src/platform/plugins/shared/unified_histogram/public/chart/lazy.tsx
rename to src/platform/packages/shared/kbn-unified-histogram/components/chart/lazy.tsx
diff --git a/src/platform/plugins/shared/unified_histogram/public/chart/time_interval_selector.test.tsx b/src/platform/packages/shared/kbn-unified-histogram/components/chart/time_interval_selector.test.tsx
similarity index 100%
rename from src/platform/plugins/shared/unified_histogram/public/chart/time_interval_selector.test.tsx
rename to src/platform/packages/shared/kbn-unified-histogram/components/chart/time_interval_selector.test.tsx
diff --git a/src/platform/plugins/shared/unified_histogram/public/chart/time_interval_selector.tsx b/src/platform/packages/shared/kbn-unified-histogram/components/chart/time_interval_selector.tsx
similarity index 97%
rename from src/platform/plugins/shared/unified_histogram/public/chart/time_interval_selector.tsx
rename to src/platform/packages/shared/kbn-unified-histogram/components/chart/time_interval_selector.tsx
index bb0250b9f4d8..da33a845ee8a 100644
--- a/src/platform/plugins/shared/unified_histogram/public/chart/time_interval_selector.tsx
+++ b/src/platform/packages/shared/kbn-unified-histogram/components/chart/time_interval_selector.tsx
@@ -11,7 +11,7 @@ import React, { useCallback } from 'react';
import { EuiSelectableOption } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import { search } from '@kbn/data-plugin/public';
-import type { UnifiedHistogramChartContext } from '../types';
+import type { UnifiedHistogramChartContext } from '../../types';
import { ToolbarSelector, ToolbarSelectorProps, SelectableEntry } from './toolbar_selector';
export interface TimeIntervalSelectorProps {
diff --git a/src/platform/plugins/shared/unified_histogram/public/chart/toolbar_selector.tsx b/src/platform/packages/shared/kbn-unified-histogram/components/chart/toolbar_selector.tsx
similarity index 100%
rename from src/platform/plugins/shared/unified_histogram/public/chart/toolbar_selector.tsx
rename to src/platform/packages/shared/kbn-unified-histogram/components/chart/toolbar_selector.tsx
diff --git a/src/platform/plugins/shared/unified_histogram/public/chart/utils/build_bucket_interval.test.ts b/src/platform/packages/shared/kbn-unified-histogram/components/chart/utils/build_bucket_interval.test.ts
similarity index 97%
rename from src/platform/plugins/shared/unified_histogram/public/chart/utils/build_bucket_interval.test.ts
rename to src/platform/packages/shared/kbn-unified-histogram/components/chart/utils/build_bucket_interval.test.ts
index 19d35fc8f809..0065be31a195 100644
--- a/src/platform/plugins/shared/unified_histogram/public/chart/utils/build_bucket_interval.test.ts
+++ b/src/platform/packages/shared/kbn-unified-histogram/components/chart/utils/build_bucket_interval.test.ts
@@ -8,7 +8,7 @@
*/
import { dataPluginMock } from '@kbn/data-plugin/public/mocks';
-import { dataViewWithTimefieldMock } from '../../__mocks__/data_view_with_timefield';
+import { dataViewWithTimefieldMock } from '../../../__mocks__/data_view_with_timefield';
import { calculateBounds } from '@kbn/data-plugin/public';
import { buildBucketInterval } from './build_bucket_interval';
diff --git a/src/platform/plugins/shared/unified_histogram/public/chart/utils/build_bucket_interval.ts b/src/platform/packages/shared/kbn-unified-histogram/components/chart/utils/build_bucket_interval.ts
similarity index 95%
rename from src/platform/plugins/shared/unified_histogram/public/chart/utils/build_bucket_interval.ts
rename to src/platform/packages/shared/kbn-unified-histogram/components/chart/utils/build_bucket_interval.ts
index 4eea85e7e70b..c186d78b6f4e 100644
--- a/src/platform/plugins/shared/unified_histogram/public/chart/utils/build_bucket_interval.ts
+++ b/src/platform/packages/shared/kbn-unified-histogram/components/chart/utils/build_bucket_interval.ts
@@ -11,7 +11,7 @@ import type { SearchResponse } from '@elastic/elasticsearch/lib/api/types';
import { DataPublicPluginStart, search, tabifyAggResponse } from '@kbn/data-plugin/public';
import type { DataView } from '@kbn/data-views-plugin/common';
import type { TimeRange } from '@kbn/es-query';
-import type { UnifiedHistogramBucketInterval } from '../../types';
+import type { UnifiedHistogramBucketInterval } from '../../../types';
import { getChartAggConfigs } from './get_chart_agg_configs';
/**
diff --git a/src/platform/plugins/shared/unified_histogram/public/chart/check_chart_availability.ts b/src/platform/packages/shared/kbn-unified-histogram/components/chart/utils/check_chart_availability.ts
similarity index 93%
rename from src/platform/plugins/shared/unified_histogram/public/chart/check_chart_availability.ts
rename to src/platform/packages/shared/kbn-unified-histogram/components/chart/utils/check_chart_availability.ts
index b590a50abc3f..5ae60d66479b 100644
--- a/src/platform/plugins/shared/unified_histogram/public/chart/check_chart_availability.ts
+++ b/src/platform/packages/shared/kbn-unified-histogram/components/chart/utils/check_chart_availability.ts
@@ -8,7 +8,7 @@
*/
import { type DataView, DataViewType } from '@kbn/data-views-plugin/common';
-import { UnifiedHistogramChartContext } from '../types';
+import { UnifiedHistogramChartContext } from '../../../types';
export function checkChartAvailability({
chart,
diff --git a/src/platform/plugins/shared/unified_histogram/public/chart/utils/get_chart_agg_config.test.ts b/src/platform/packages/shared/kbn-unified-histogram/components/chart/utils/get_chart_agg_config.test.ts
similarity index 95%
rename from src/platform/plugins/shared/unified_histogram/public/chart/utils/get_chart_agg_config.test.ts
rename to src/platform/packages/shared/kbn-unified-histogram/components/chart/utils/get_chart_agg_config.test.ts
index 951825e1500b..3055d4473247 100644
--- a/src/platform/plugins/shared/unified_histogram/public/chart/utils/get_chart_agg_config.test.ts
+++ b/src/platform/packages/shared/kbn-unified-histogram/components/chart/utils/get_chart_agg_config.test.ts
@@ -7,7 +7,7 @@
* License v3.0 only", or the "Server Side Public License, v 1".
*/
-import { dataViewWithTimefieldMock } from '../../__mocks__/data_view_with_timefield';
+import { dataViewWithTimefieldMock } from '../../../__mocks__/data_view_with_timefield';
import { dataPluginMock } from '@kbn/data-plugin/public/mocks';
import { getChartAggConfigs } from './get_chart_agg_configs';
diff --git a/src/platform/plugins/shared/unified_histogram/public/chart/utils/get_chart_agg_configs.ts b/src/platform/packages/shared/kbn-unified-histogram/components/chart/utils/get_chart_agg_configs.ts
similarity index 100%
rename from src/platform/plugins/shared/unified_histogram/public/chart/utils/get_chart_agg_configs.ts
rename to src/platform/packages/shared/kbn-unified-histogram/components/chart/utils/get_chart_agg_configs.ts
diff --git a/src/platform/plugins/shared/unified_histogram/public/chart/index.ts b/src/platform/packages/shared/kbn-unified-histogram/components/layout/index.ts
similarity index 82%
rename from src/platform/plugins/shared/unified_histogram/public/chart/index.ts
rename to src/platform/packages/shared/kbn-unified-histogram/components/layout/index.ts
index 73a235df8d8a..eaaa5f4cb118 100644
--- a/src/platform/plugins/shared/unified_histogram/public/chart/index.ts
+++ b/src/platform/packages/shared/kbn-unified-histogram/components/layout/index.ts
@@ -7,5 +7,4 @@
* License v3.0 only", or the "Server Side Public License, v 1".
*/
-export { Chart } from './chart';
-export { checkChartAvailability } from './check_chart_availability';
+export { UnifiedHistogramLayout, type UnifiedHistogramLayoutProps } from './layout';
diff --git a/src/platform/plugins/shared/unified_histogram/public/layout/layout.test.tsx b/src/platform/packages/shared/kbn-unified-histogram/components/layout/layout.test.tsx
similarity index 64%
rename from src/platform/plugins/shared/unified_histogram/public/layout/layout.test.tsx
rename to src/platform/packages/shared/kbn-unified-histogram/components/layout/layout.test.tsx
index 48c5d361d1c0..f3d4163272fe 100644
--- a/src/platform/plugins/shared/unified_histogram/public/layout/layout.test.tsx
+++ b/src/platform/packages/shared/kbn-unified-histogram/components/layout/layout.test.tsx
@@ -12,16 +12,18 @@ import { mountWithIntl } from '@kbn/test-jest-helpers';
import type { ReactWrapper } from 'enzyme';
import React from 'react';
import { of } from 'rxjs';
-import { Chart } from '../chart';
+import { UnifiedHistogramChart } from '../chart';
import {
UnifiedHistogramChartContext,
UnifiedHistogramFetchStatus,
UnifiedHistogramHitsContext,
-} from '../types';
-import { dataViewWithTimefieldMock } from '../__mocks__/data_view_with_timefield';
-import { unifiedHistogramServicesMock } from '../__mocks__/services';
-import { UnifiedHistogramLayout, UnifiedHistogramLayoutProps } from './layout';
+} from '../../types';
+import { dataViewWithTimefieldMock } from '../../__mocks__/data_view_with_timefield';
+import { unifiedHistogramServicesMock } from '../../__mocks__/services';
+import { UnifiedHistogramLayout } from './layout';
import { ResizableLayout, ResizableLayoutMode } from '@kbn/resizable-layout';
+import { UseUnifiedHistogramProps, useUnifiedHistogram } from '../../hooks/use_unified_histogram';
+import { act } from 'react-dom/test-utils';
let mockBreakpoint = 'l';
@@ -36,54 +38,65 @@ jest.mock('@elastic/eui', () => {
});
describe('Layout', () => {
- const createHits = (): UnifiedHistogramHitsContext => ({
- status: UnifiedHistogramFetchStatus.complete,
- total: 10,
- });
-
- const createChart = (): UnifiedHistogramChartContext => ({
- hidden: false,
- timeInterval: 'auto',
- });
-
const mountComponent = async ({
services = unifiedHistogramServicesMock,
- hits = createHits(),
- chart = createChart(),
- container = null,
+ hits,
+ chart,
+ topPanelHeight,
...rest
- }: Partial> & {
+ }: Partial & {
hits?: UnifiedHistogramHitsContext | null;
chart?: UnifiedHistogramChartContext | null;
+ topPanelHeight?: number | null;
} = {}) => {
(searchSourceInstanceMock.fetch$ as jest.Mock).mockImplementation(
jest.fn().mockReturnValue(of({ rawResponse: { hits: { total: 2 } } }))
);
-
- const component = mountWithIntl(
- {
+ const unifiedHistogram = useUnifiedHistogram({
+ services,
+ initialState: {
+ totalHitsStatus: hits?.status ?? UnifiedHistogramFetchStatus.complete,
+ totalHitsResult: hits?.total ?? 10,
+ chartHidden: chart?.hidden ?? false,
+ timeInterval: chart?.timeInterval ?? 'auto',
+ },
+ dataView: dataViewWithTimefieldMock,
+ query: {
language: 'kuery',
query: '',
- }}
- filters={[]}
- timeRange={{
+ },
+ filters: [],
+ timeRange: {
from: '2020-05-14T11:05:13.590',
to: '2020-05-14T11:20:13.590',
- }}
- lensSuggestionsApi={jest.fn()}
- onSuggestionContextChange={jest.fn()}
- isChartLoading={false}
- {...rest}
- />
- );
+ },
+ isChartLoading: false,
+ ...rest,
+ });
- return component;
+ if (!unifiedHistogram.isInitialized) {
+ return null;
+ }
+
+ return (
+ }
+ {...unifiedHistogram.layoutProps}
+ hits={hits === undefined ? unifiedHistogram.layoutProps.hits : hits ?? undefined}
+ chart={chart === undefined ? unifiedHistogram.layoutProps.chart : chart ?? undefined}
+ topPanelHeight={
+ topPanelHeight === undefined
+ ? unifiedHistogram.layoutProps.topPanelHeight
+ : topPanelHeight ?? undefined
+ }
+ />
+ );
+ };
+ const component = mountWithIntl();
+ await act(() => new Promise((resolve) => setTimeout(resolve, 0)));
+ return component.update();
};
const setBreakpoint = (component: ReactWrapper, breakpoint: string) => {
@@ -109,12 +122,7 @@ describe('Layout', () => {
});
it('should set the layout mode to ResizableLayoutMode.Static if chart.hidden is true', async () => {
- const component = await mountComponent({
- chart: {
- ...createChart(),
- hidden: true,
- },
- });
+ const component = await mountComponent({ chart: { timeInterval: 'auto', hidden: true } });
expect(component.find(ResizableLayout).prop('mode')).toBe(ResizableLayoutMode.Static);
});
@@ -132,16 +140,20 @@ describe('Layout', () => {
const component = await mountComponent();
setBreakpoint(component, 's');
const expectedHeight = component.find(ResizableLayout).prop('fixedPanelSize');
- expect(component.find(Chart).find('div.euiFlexGroup').first().getDOMNode()).toHaveStyle({
+ expect(
+ component.find(UnifiedHistogramChart).find('div.euiFlexGroup').first().getDOMNode()
+ ).toHaveStyle({
height: `${expectedHeight}px`,
});
});
it('should not set a fixed height for Chart when layout mode is ResizableLayoutMode.Static and chart.hidden is true', async () => {
- const component = await mountComponent({ chart: { ...createChart(), hidden: true } });
+ const component = await mountComponent({ chart: { timeInterval: 'auto', hidden: true } });
setBreakpoint(component, 's');
const expectedHeight = component.find(ResizableLayout).prop('fixedPanelSize');
- expect(component.find(Chart).find('div.euiFlexGroup').first().getDOMNode()).not.toHaveStyle({
+ expect(
+ component.find(UnifiedHistogramChart).find('div.euiFlexGroup').first().getDOMNode()
+ ).not.toHaveStyle({
height: `${expectedHeight}px`,
});
});
@@ -150,7 +162,9 @@ describe('Layout', () => {
const component = await mountComponent({ chart: null });
setBreakpoint(component, 's');
const expectedHeight = component.find(ResizableLayout).prop('fixedPanelSize');
- expect(component.find(Chart).find('div.euiFlexGroup').first().getDOMNode()).not.toHaveStyle({
+ expect(
+ component.find(UnifiedHistogramChart).find('div.euiFlexGroup').first().getDOMNode()
+ ).not.toHaveStyle({
height: `${expectedHeight}px`,
});
});
@@ -158,7 +172,7 @@ describe('Layout', () => {
describe('topPanelHeight', () => {
it('should pass a default fixedPanelSize to ResizableLayout when the topPanelHeight prop is undefined', async () => {
- const component = await mountComponent({ topPanelHeight: undefined });
+ const component = await mountComponent({ topPanelHeight: null });
expect(component.find(ResizableLayout).prop('fixedPanelSize')).toBeGreaterThan(0);
});
});
diff --git a/src/platform/packages/shared/kbn-unified-histogram/components/layout/layout.tsx b/src/platform/packages/shared/kbn-unified-histogram/components/layout/layout.tsx
new file mode 100644
index 000000000000..93f73edb75ba
--- /dev/null
+++ b/src/platform/packages/shared/kbn-unified-histogram/components/layout/layout.tsx
@@ -0,0 +1,116 @@
+/*
+ * 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", the "GNU Affero General Public License v3.0 only", and the "Server Side
+ * Public License v 1"; you may not use this file except in compliance with, at
+ * your election, the "Elastic License 2.0", the "GNU Affero General Public
+ * License v3.0 only", or the "Server Side Public License, v 1".
+ */
+
+import { euiFullHeight, useEuiTheme, useIsWithinBreakpoints } from '@elastic/eui';
+import React, { PropsWithChildren, ReactNode, useState } from 'react';
+import { createHtmlPortalNode, InPortal, OutPortal } from 'react-reverse-portal';
+import {
+ ResizableLayout,
+ ResizableLayoutDirection,
+ ResizableLayoutMode,
+} from '@kbn/resizable-layout';
+import { css } from '@emotion/react';
+import { UnifiedHistogramChartContext, UnifiedHistogramHitsContext } from '../../types';
+
+export type UnifiedHistogramLayoutProps = PropsWithChildren<{
+ /**
+ * The parent container element, used to calculate the layout size
+ */
+ container: HTMLElement | null;
+ /**
+ * The rendered UnifiedHistogramChart component
+ */
+ unifiedHistogramChart: ReactNode;
+ /**
+ * Context object for the chart -- leave undefined to hide the chart
+ */
+ chart?: UnifiedHistogramChartContext;
+ /**
+ * Flag to indicate if the chart is available for rendering
+ */
+ isChartAvailable?: boolean;
+ /**
+ * Context object for the hits count -- leave undefined to hide the hits count
+ */
+ hits?: UnifiedHistogramHitsContext;
+ /**
+ * Current top panel height -- leave undefined to use the default
+ */
+ topPanelHeight?: number;
+ /**
+ * Callback to update the topPanelHeight prop when a resize is triggered
+ */
+ onTopPanelHeightChange?: (topPanelHeight: number | undefined) => void;
+}>;
+
+export const UnifiedHistogramLayout = ({
+ container,
+ unifiedHistogramChart,
+ chart,
+ isChartAvailable,
+ hits,
+ topPanelHeight,
+ onTopPanelHeightChange,
+ children,
+}: UnifiedHistogramLayoutProps) => {
+ const [mainPanelNode] = useState(() =>
+ createHtmlPortalNode({ attributes: { class: 'eui-fullHeight' } })
+ );
+
+ const isMobile = useIsWithinBreakpoints(['xs', 's']);
+ const showFixedPanels = isMobile || !chart || chart.hidden;
+ const { euiTheme } = useEuiTheme();
+ const defaultTopPanelHeight = euiTheme.base * 12;
+ const minMainPanelHeight = euiTheme.base * 10;
+
+ const chartCss =
+ isMobile && chart && !chart.hidden
+ ? css`
+ .unifiedHistogram__chart {
+ height: ${defaultTopPanelHeight}px;
+ }
+ `
+ : css`
+ .unifiedHistogram__chart {
+ ${euiFullHeight()}
+ }
+ `;
+
+ const panelsMode =
+ chart || hits
+ ? showFixedPanels
+ ? ResizableLayoutMode.Static
+ : ResizableLayoutMode.Resizable
+ : ResizableLayoutMode.Single;
+
+ const currentTopPanelHeight = topPanelHeight ?? defaultTopPanelHeight;
+
+ return (
+ <>
+
+ {React.isValidElement<{ isChartAvailable?: boolean }>(children)
+ ? React.cloneElement(children, { isChartAvailable })
+ : children}
+
+ }
+ data-test-subj="unifiedHistogram"
+ css={chartCss}
+ onFixedPanelSizeChange={onTopPanelHeightChange}
+ />
+ >
+ );
+};
diff --git a/src/platform/plugins/shared/unified_histogram/public/hooks/use_request_params.test.ts b/src/platform/packages/shared/kbn-unified-histogram/hooks/use_request_params.test.ts
similarity index 100%
rename from src/platform/plugins/shared/unified_histogram/public/hooks/use_request_params.test.ts
rename to src/platform/packages/shared/kbn-unified-histogram/hooks/use_request_params.test.ts
diff --git a/src/platform/plugins/shared/unified_histogram/public/hooks/use_request_params.tsx b/src/platform/packages/shared/kbn-unified-histogram/hooks/use_request_params.tsx
similarity index 100%
rename from src/platform/plugins/shared/unified_histogram/public/hooks/use_request_params.tsx
rename to src/platform/packages/shared/kbn-unified-histogram/hooks/use_request_params.tsx
diff --git a/src/platform/plugins/shared/unified_histogram/public/hooks/use_stable_callback.test.ts b/src/platform/packages/shared/kbn-unified-histogram/hooks/use_stable_callback.test.ts
similarity index 100%
rename from src/platform/plugins/shared/unified_histogram/public/hooks/use_stable_callback.test.ts
rename to src/platform/packages/shared/kbn-unified-histogram/hooks/use_stable_callback.test.ts
diff --git a/src/platform/plugins/shared/unified_histogram/public/hooks/use_stable_callback.ts b/src/platform/packages/shared/kbn-unified-histogram/hooks/use_stable_callback.ts
similarity index 100%
rename from src/platform/plugins/shared/unified_histogram/public/hooks/use_stable_callback.ts
rename to src/platform/packages/shared/kbn-unified-histogram/hooks/use_stable_callback.ts
diff --git a/src/platform/plugins/shared/unified_histogram/public/container/hooks/use_state_props.test.ts b/src/platform/packages/shared/kbn-unified-histogram/hooks/use_state_props.test.ts
similarity index 95%
rename from src/platform/plugins/shared/unified_histogram/public/container/hooks/use_state_props.test.ts
rename to src/platform/packages/shared/kbn-unified-histogram/hooks/use_state_props.test.ts
index 94912430db48..2ca6ed269446 100644
--- a/src/platform/plugins/shared/unified_histogram/public/container/hooks/use_state_props.test.ts
+++ b/src/platform/packages/shared/kbn-unified-histogram/hooks/use_state_props.test.ts
@@ -12,11 +12,11 @@ import { RequestAdapter } from '@kbn/inspector-plugin/common';
import { waitFor, renderHook, act } from '@testing-library/react';
import type { DatatableColumn } from '@kbn/expressions-plugin/common';
import { convertDatatableColumnToDataViewFieldSpec } from '@kbn/data-view-utils';
-import { UnifiedHistogramFetchStatus, UnifiedHistogramSuggestionContext } from '../../types';
-import { dataViewMock } from '../../__mocks__/data_view';
-import { dataViewWithTimefieldMock } from '../../__mocks__/data_view_with_timefield';
-import { lensAdaptersMock } from '../../__mocks__/lens_adapters';
-import { unifiedHistogramServicesMock } from '../../__mocks__/services';
+import { UnifiedHistogramFetchStatus, UnifiedHistogramSuggestionContext } from '../types';
+import { dataViewMock } from '../__mocks__/data_view';
+import { dataViewWithTimefieldMock } from '../__mocks__/data_view_with_timefield';
+import { lensAdaptersMock } from '../__mocks__/lens_adapters';
+import { unifiedHistogramServicesMock } from '../__mocks__/services';
import {
createStateService,
UnifiedHistogramState,
@@ -64,6 +64,7 @@ describe('useStateProps', () => {
columns: undefined,
breakdownField: undefined,
onBreakdownFieldChange: undefined,
+ onVisContextChanged: undefined,
})
);
expect(result.current).toMatchInlineSnapshot(`
@@ -123,6 +124,7 @@ describe('useStateProps', () => {
"onTimeIntervalChange": [Function],
"onTopPanelHeightChange": [Function],
"onTotalHitsChange": [Function],
+ "onVisContextChanged": undefined,
"request": Object {
"adapter": RequestAdapter {
"_events": Object {},
@@ -135,6 +137,7 @@ describe('useStateProps', () => {
},
"searchSessionId": "123",
},
+ "topPanelHeight": 100,
}
`);
});
@@ -153,6 +156,7 @@ describe('useStateProps', () => {
columns: undefined,
breakdownField: undefined,
onBreakdownFieldChange: undefined,
+ onVisContextChanged: undefined,
})
);
expect(result.current).toMatchInlineSnapshot(`
@@ -212,6 +216,7 @@ describe('useStateProps', () => {
"onTimeIntervalChange": [Function],
"onTopPanelHeightChange": [Function],
"onTotalHitsChange": [Function],
+ "onVisContextChanged": undefined,
"request": Object {
"adapter": RequestAdapter {
"_events": Object {},
@@ -224,6 +229,7 @@ describe('useStateProps', () => {
},
"searchSessionId": "123",
},
+ "topPanelHeight": 100,
}
`);
@@ -251,6 +257,7 @@ describe('useStateProps', () => {
columns: undefined,
breakdownField: undefined,
onBreakdownFieldChange: undefined,
+ onVisContextChanged: undefined,
})
);
expect(result.current.chart).toStrictEqual({ hidden: false, timeInterval: 'auto' });
@@ -290,6 +297,7 @@ describe('useStateProps', () => {
columns: esqlColumns,
breakdownField,
onBreakdownFieldChange: undefined,
+ onVisContextChanged: undefined,
})
);
@@ -332,6 +340,7 @@ describe('useStateProps', () => {
columns: esqlColumns,
breakdownField: undefined,
onBreakdownFieldChange: undefined,
+ onVisContextChanged: undefined,
})
);
const { onBreakdownFieldChange } = result.current;
@@ -357,6 +366,7 @@ describe('useStateProps', () => {
columns: undefined,
breakdownField: undefined,
onBreakdownFieldChange: undefined,
+ onVisContextChanged: undefined,
})
);
expect(result.current).toMatchInlineSnapshot(`
@@ -411,6 +421,7 @@ describe('useStateProps', () => {
"onTimeIntervalChange": [Function],
"onTopPanelHeightChange": [Function],
"onTotalHitsChange": [Function],
+ "onVisContextChanged": undefined,
"request": Object {
"adapter": RequestAdapter {
"_events": Object {},
@@ -423,6 +434,7 @@ describe('useStateProps', () => {
},
"searchSessionId": "123",
},
+ "topPanelHeight": 100,
}
`);
});
@@ -441,6 +453,7 @@ describe('useStateProps', () => {
columns: undefined,
breakdownField: undefined,
onBreakdownFieldChange: undefined,
+ onVisContextChanged: undefined,
})
);
expect(result.current).toMatchInlineSnapshot(`
@@ -495,6 +508,7 @@ describe('useStateProps', () => {
"onTimeIntervalChange": [Function],
"onTopPanelHeightChange": [Function],
"onTotalHitsChange": [Function],
+ "onVisContextChanged": undefined,
"request": Object {
"adapter": RequestAdapter {
"_events": Object {},
@@ -507,6 +521,7 @@ describe('useStateProps', () => {
},
"searchSessionId": "123",
},
+ "topPanelHeight": 100,
}
`);
});
@@ -525,6 +540,7 @@ describe('useStateProps', () => {
columns: undefined,
breakdownField: undefined,
onBreakdownFieldChange: undefined,
+ onVisContextChanged: undefined,
})
);
@@ -602,6 +618,7 @@ describe('useStateProps', () => {
columns: undefined,
breakdownField: undefined,
onBreakdownFieldChange: undefined,
+ onVisContextChanged: undefined,
})
);
(stateService.setLensRequestAdapter as jest.Mock).mockClear();
@@ -626,6 +643,7 @@ describe('useStateProps', () => {
columns: undefined,
breakdownField: undefined,
onBreakdownFieldChange: undefined,
+ onVisContextChanged: undefined,
};
const hook = renderHook((props: Parameters[0]) => useStateProps(props), {
initialProps,
diff --git a/src/platform/plugins/shared/unified_histogram/public/container/hooks/use_state_props.ts b/src/platform/packages/shared/kbn-unified-histogram/hooks/use_state_props.ts
similarity index 84%
rename from src/platform/plugins/shared/unified_histogram/public/container/hooks/use_state_props.ts
rename to src/platform/packages/shared/kbn-unified-histogram/hooks/use_state_props.ts
index 46244d69d1f8..a1084a94c5c0 100644
--- a/src/platform/plugins/shared/unified_histogram/public/container/hooks/use_state_props.ts
+++ b/src/platform/packages/shared/kbn-unified-histogram/hooks/use_state_props.ts
@@ -16,10 +16,12 @@ import { convertDatatableColumnToDataViewFieldSpec } from '@kbn/data-view-utils'
import { useCallback, useEffect, useMemo } from 'react';
import {
UnifiedHistogramChartLoadEvent,
+ UnifiedHistogramExternalVisContextStatus,
UnifiedHistogramFetchStatus,
UnifiedHistogramServices,
UnifiedHistogramSuggestionContext,
-} from '../../types';
+ UnifiedHistogramVisContext,
+} from '../types';
import type { UnifiedHistogramStateService } from '../services/state_service';
import {
chartHiddenSelector,
@@ -28,9 +30,12 @@ import {
totalHitsStatusSelector,
lensAdaptersSelector,
lensDataLoadingSelector$,
+ topPanelHeightSelector,
} from '../utils/state_selectors';
-import { useStateSelector } from '../utils/use_state_selector';
+import { useStateSelector } from './use_state_selector';
import { setBreakdownField } from '../utils/local_storage_utils';
+import { exportVisContext } from '../utils/external_vis_context';
+import { UseUnifiedHistogramProps } from './use_unified_histogram';
export const useStateProps = ({
services,
@@ -43,6 +48,7 @@ export const useStateProps = ({
columns,
breakdownField,
onBreakdownFieldChange: originalOnBreakdownFieldChange,
+ onVisContextChanged: originalOnVisContextChanged,
}: {
services: UnifiedHistogramServices;
localStorageKeyPrefix: string | undefined;
@@ -54,13 +60,21 @@ export const useStateProps = ({
columns: DatatableColumn[] | undefined;
breakdownField: string | undefined;
onBreakdownFieldChange: ((breakdownField: string | undefined) => void) | undefined;
+ onVisContextChanged:
+ | ((
+ nextVisContext: UnifiedHistogramVisContext | undefined,
+ externalVisContextStatus: UnifiedHistogramExternalVisContextStatus
+ ) => void)
+ | undefined;
}) => {
+ const topPanelHeight = useStateSelector(stateService?.state$, topPanelHeightSelector);
const chartHidden = useStateSelector(stateService?.state$, chartHiddenSelector);
const timeInterval = useStateSelector(stateService?.state$, timeIntervalSelector);
const totalHitsResult = useStateSelector(stateService?.state$, totalHitsResultSelector);
const totalHitsStatus = useStateSelector(stateService?.state$, totalHitsStatusSelector);
const lensAdapters = useStateSelector(stateService?.state$, lensAdaptersSelector);
const lensDataLoading$ = useStateSelector(stateService?.state$, lensDataLoadingSelector$);
+
/**
* Contexts
*/
@@ -132,8 +146,8 @@ export const useStateProps = ({
*/
const onTopPanelHeightChange = useCallback(
- (topPanelHeight: number | undefined) => {
- stateService?.setTopPanelHeight(topPanelHeight);
+ (newTopPanelHeight: number | undefined) => {
+ stateService?.setTopPanelHeight(newTopPanelHeight);
},
[stateService]
);
@@ -186,6 +200,18 @@ export const useStateProps = ({
[stateService]
);
+ const onVisContextChanged: UseUnifiedHistogramProps['onVisContextChanged'] = useMemo(() => {
+ if (!originalOnVisContextChanged || !isPlainRecord) {
+ return undefined;
+ }
+
+ return (visContext, externalVisContextStatus) => {
+ const minifiedVisContext = exportVisContext(visContext);
+
+ originalOnVisContextChanged(minifiedVisContext, externalVisContextStatus);
+ };
+ }, [isPlainRecord, originalOnVisContextChanged]);
+
/**
* Effects
*/
@@ -205,6 +231,7 @@ export const useStateProps = ({
}, [chart, chartHidden, stateService]);
return {
+ topPanelHeight,
hits,
chart,
breakdown,
@@ -219,5 +246,6 @@ export const useStateProps = ({
onChartLoad,
onBreakdownFieldChange,
onSuggestionContextChange,
+ onVisContextChanged,
};
};
diff --git a/src/platform/plugins/shared/unified_histogram/public/container/utils/use_state_selector.ts b/src/platform/packages/shared/kbn-unified-histogram/hooks/use_state_selector.ts
similarity index 100%
rename from src/platform/plugins/shared/unified_histogram/public/container/utils/use_state_selector.ts
rename to src/platform/packages/shared/kbn-unified-histogram/hooks/use_state_selector.ts
diff --git a/src/platform/packages/shared/kbn-unified-histogram/hooks/use_unified_histogram.test.tsx b/src/platform/packages/shared/kbn-unified-histogram/hooks/use_unified_histogram.test.tsx
new file mode 100644
index 000000000000..c0a7ebfdf68c
--- /dev/null
+++ b/src/platform/packages/shared/kbn-unified-histogram/hooks/use_unified_histogram.test.tsx
@@ -0,0 +1,68 @@
+/*
+ * 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", the "GNU Affero General Public License v3.0 only", and the "Server Side
+ * Public License v 1"; you may not use this file except in compliance with, at
+ * your election, the "Elastic License 2.0", the "GNU Affero General Public
+ * License v3.0 only", or the "Server Side Public License, v 1".
+ */
+
+import { RequestAdapter } from '@kbn/inspector-plugin/common';
+import { act } from 'react-dom/test-utils';
+import { dataViewWithTimefieldMock } from '../__mocks__/data_view_with_timefield';
+import { unifiedHistogramServicesMock } from '../__mocks__/services';
+import { useUnifiedHistogram } from './use_unified_histogram';
+import { renderHook, waitFor } from '@testing-library/react';
+
+describe('useUnifiedHistogram', () => {
+ it('should initialize', async () => {
+ const hook = renderHook(() =>
+ useUnifiedHistogram({
+ services: unifiedHistogramServicesMock,
+ initialState: { timeInterval: '42s' },
+ dataView: dataViewWithTimefieldMock,
+ filters: [],
+ query: { language: 'kuery', query: '' },
+ requestAdapter: new RequestAdapter(),
+ searchSessionId: '123',
+ timeRange: { from: 'now-15m', to: 'now' },
+ })
+ );
+ expect(hook.result.current.isInitialized).toBe(false);
+ expect(hook.result.current.api).toBeUndefined();
+ expect(hook.result.current.chartProps).toBeUndefined();
+ expect(hook.result.current.layoutProps).toBeUndefined();
+ await waitFor(() => {
+ expect(hook.result.current.isInitialized).toBe(true);
+ });
+ expect(hook.result.current.api).toBeDefined();
+ expect(hook.result.current.chartProps?.chart?.timeInterval).toBe('42s');
+ expect(hook.result.current.layoutProps).toBeDefined();
+ });
+
+ it('should trigger input$ when fetch is called', async () => {
+ const { result } = renderHook(() =>
+ useUnifiedHistogram({
+ services: unifiedHistogramServicesMock,
+ initialState: { timeInterval: '42s' },
+ dataView: dataViewWithTimefieldMock,
+ filters: [],
+ query: { language: 'kuery', query: '' },
+ requestAdapter: new RequestAdapter(),
+ searchSessionId: '123',
+ timeRange: { from: 'now-15m', to: 'now' },
+ })
+ );
+ await waitFor(() => {
+ expect(result.current.isInitialized).toBe(true);
+ });
+ const input$ = result.current.chartProps?.input$;
+ const inputSpy = jest.fn();
+ input$?.subscribe(inputSpy);
+ act(() => {
+ result.current.api?.fetch();
+ });
+ expect(inputSpy).toHaveBeenCalledTimes(1);
+ expect(inputSpy).toHaveBeenCalledWith({ type: 'fetch' });
+ });
+});
diff --git a/src/platform/packages/shared/kbn-unified-histogram/hooks/use_unified_histogram.ts b/src/platform/packages/shared/kbn-unified-histogram/hooks/use_unified_histogram.ts
new file mode 100644
index 000000000000..fcaf695708e4
--- /dev/null
+++ b/src/platform/packages/shared/kbn-unified-histogram/hooks/use_unified_histogram.ts
@@ -0,0 +1,324 @@
+/*
+ * 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", the "GNU Affero General Public License v3.0 only", and the "Server Side
+ * Public License v 1"; you may not use this file except in compliance with, at
+ * your election, the "Elastic License 2.0", the "GNU Affero General Public
+ * License v3.0 only", or the "Server Side Public License, v 1".
+ */
+
+import { AggregateQuery, Filter, Query, TimeRange } from '@kbn/es-query';
+import type { Datatable, DatatableColumn } from '@kbn/expressions-plugin/public';
+import type { EmbeddableComponentProps, LensEmbeddableInput } from '@kbn/lens-plugin/public';
+import { useEffect, useMemo, useState } from 'react';
+import { Observable, Subject, of } from 'rxjs';
+import useMount from 'react-use/lib/useMount';
+import { pick } from 'lodash';
+import type { DataView } from '@kbn/data-views-plugin/common';
+import useObservable from 'react-use/lib/useObservable';
+import { UnifiedHistogramChartProps } from '../components/chart/chart';
+import {
+ UnifiedHistogramExternalVisContextStatus,
+ UnifiedHistogramInputMessage,
+ UnifiedHistogramRequestContext,
+ UnifiedHistogramServices,
+ UnifiedHistogramSuggestionContext,
+ UnifiedHistogramSuggestionType,
+ UnifiedHistogramVisContext,
+} from '../types';
+import {
+ UnifiedHistogramStateOptions,
+ UnifiedHistogramStateService,
+ createStateService,
+} from '../services/state_service';
+import { useStateProps } from './use_state_props';
+import { useRequestParams } from './use_request_params';
+import { LensVisService } from '../services/lens_vis_service';
+import { checkChartAvailability } from '../components/chart';
+import { UnifiedHistogramLayoutProps } from '../components/layout/layout';
+import { getBreakdownField } from '../utils/local_storage_utils';
+
+export type UseUnifiedHistogramProps = Omit & {
+ /**
+ * Required services
+ */
+ services: UnifiedHistogramServices;
+ /**
+ * The current search session ID
+ */
+ searchSessionId?: UnifiedHistogramRequestContext['searchSessionId'];
+ /**
+ * The request adapter to use for the inspector
+ */
+ requestAdapter?: UnifiedHistogramRequestContext['adapter'];
+ /**
+ * The abort controller to use for requests
+ */
+ abortController?: AbortController;
+ /**
+ * The current data view
+ */
+ dataView: DataView;
+ /**
+ * The current query
+ */
+ query?: Query | AggregateQuery;
+ /**
+ * The current filters
+ */
+ filters?: Filter[];
+ /**
+ * The current breakdown field
+ */
+ breakdownField?: string;
+ /**
+ * The external custom Lens vis
+ */
+ externalVisContext?: UnifiedHistogramVisContext;
+ /**
+ * The current time range
+ */
+ timeRange?: TimeRange;
+ /**
+ * The relative time range, used when timeRange is an absolute range (e.g. for edit visualization button)
+ */
+ relativeTimeRange?: TimeRange;
+ /**
+ * The current columns
+ */
+ columns?: DatatableColumn[];
+ /**
+ * Preloaded data table sometimes used for rendering the chart in ES|QL mode
+ */
+ table?: Datatable;
+ /**
+ * Flag indicating that the chart is currently loading
+ */
+ isChartLoading?: boolean;
+ /**
+ * Allows users to enable/disable default actions
+ */
+ withDefaultActions?: EmbeddableComponentProps['withDefaultActions'];
+ /**
+ * Disabled action IDs for the Lens embeddable
+ */
+ disabledActions?: LensEmbeddableInput['disabledActions'];
+ /**
+ * Callback to pass to the Lens embeddable to handle filter changes
+ */
+ onFilter?: LensEmbeddableInput['onFilter'];
+ /**
+ * Callback to pass to the Lens embeddable to handle brush events
+ */
+ onBrushEnd?: LensEmbeddableInput['onBrushEnd'];
+ /**
+ * Callback to update the breakdown field -- should set {@link UnifiedHistogramBreakdownContext.field} to breakdownField
+ */
+ onBreakdownFieldChange?: (breakdownField: string | undefined) => void;
+ /**
+ * Callback to notify about the change in Lens attributes
+ */
+ onVisContextChanged?: (
+ nextVisContext: UnifiedHistogramVisContext | undefined,
+ externalVisContextStatus: UnifiedHistogramExternalVisContextStatus
+ ) => void;
+};
+
+export type UnifiedHistogramApi = {
+ /**
+ * Trigger a fetch of the data
+ */
+ fetch: () => void;
+} & Pick<
+ UnifiedHistogramStateService,
+ 'state$' | 'setChartHidden' | 'setTopPanelHeight' | 'setTimeInterval' | 'setTotalHits'
+>;
+
+export type UnifiedHistogramPartialLayoutProps = Omit<
+ UnifiedHistogramLayoutProps,
+ 'container' | 'unifiedHistogramChart'
+>;
+
+export type UseUnifiedHistogramResult =
+ | { isInitialized: false; api?: undefined; chartProps?: undefined; layoutProps?: undefined }
+ | {
+ isInitialized: true;
+ api: UnifiedHistogramApi;
+ chartProps: UnifiedHistogramChartProps;
+ layoutProps: UnifiedHistogramPartialLayoutProps;
+ };
+
+const EMPTY_SUGGESTION_CONTEXT: Observable = of({
+ suggestion: undefined,
+ type: UnifiedHistogramSuggestionType.unsupported,
+});
+
+export const useUnifiedHistogram = (props: UseUnifiedHistogramProps): UseUnifiedHistogramResult => {
+ const [stateService] = useState(() => {
+ const { services, initialState, localStorageKeyPrefix } = props;
+ return createStateService({ services, initialState, localStorageKeyPrefix });
+ });
+ const [lensVisService, setLensVisService] = useState();
+ const [input$] = useState(() => new Subject());
+ const [api, setApi] = useState();
+
+ // Load async services and initialize API
+ useMount(async () => {
+ const apiHelper = await services.lens.stateHelperApi();
+ setLensVisService(new LensVisService({ services, lensSuggestionsApi: apiHelper.suggestions }));
+ setApi({
+ fetch: () => {
+ input$.next({ type: 'fetch' });
+ },
+ ...pick(
+ stateService,
+ 'state$',
+ 'setChartHidden',
+ 'setTopPanelHeight',
+ 'setTimeInterval',
+ 'setTotalHits'
+ ),
+ });
+ });
+
+ const {
+ services,
+ dataView,
+ query,
+ columns,
+ searchSessionId,
+ requestAdapter,
+ isChartLoading,
+ localStorageKeyPrefix,
+ filters,
+ timeRange,
+ table,
+ externalVisContext,
+ } = props;
+ const initialBreakdownField = useMemo(
+ () =>
+ localStorageKeyPrefix
+ ? getBreakdownField(services.storage, localStorageKeyPrefix)
+ : undefined,
+ [localStorageKeyPrefix, services.storage]
+ );
+ const stateProps = useStateProps({
+ services,
+ localStorageKeyPrefix,
+ stateService,
+ dataView,
+ query,
+ searchSessionId,
+ requestAdapter,
+ columns,
+ breakdownField: 'breakdownField' in props ? props.breakdownField : initialBreakdownField,
+ onBreakdownFieldChange: props.onBreakdownFieldChange,
+ onVisContextChanged: props.onVisContextChanged,
+ });
+ const columnsMap = useMemo(() => {
+ return columns?.reduce>((acc, column) => {
+ acc[column.id] = column;
+ return acc;
+ }, {});
+ }, [columns]);
+ const requestParams = useRequestParams({
+ services,
+ query,
+ filters,
+ timeRange,
+ });
+ const lensVisServiceCurrentSuggestionContext = useObservable(
+ lensVisService?.currentSuggestionContext$ ?? EMPTY_SUGGESTION_CONTEXT
+ );
+
+ useEffect(() => {
+ if (isChartLoading || !lensVisService) {
+ return;
+ }
+
+ lensVisService.update({
+ externalVisContext,
+ queryParams: {
+ dataView,
+ query: requestParams.query,
+ filters: requestParams.filters,
+ timeRange,
+ isPlainRecord: stateProps.isPlainRecord,
+ columns,
+ columnsMap,
+ },
+ timeInterval: stateProps.chart?.timeInterval,
+ breakdownField: stateProps.breakdown?.field,
+ table,
+ onSuggestionContextChange: stateProps.onSuggestionContextChange,
+ onVisContextChanged: stateProps.onVisContextChanged,
+ });
+ }, [
+ columns,
+ columnsMap,
+ dataView,
+ externalVisContext,
+ isChartLoading,
+ lensVisService,
+ requestParams.filters,
+ requestParams.query,
+ stateProps.breakdown?.field,
+ stateProps.chart?.timeInterval,
+ stateProps.isPlainRecord,
+ stateProps.onSuggestionContextChange,
+ stateProps.onVisContextChanged,
+ table,
+ timeRange,
+ ]);
+
+ const chart =
+ !lensVisServiceCurrentSuggestionContext?.type ||
+ lensVisServiceCurrentSuggestionContext.type === UnifiedHistogramSuggestionType.unsupported
+ ? undefined
+ : stateProps.chart;
+ const isChartAvailable = checkChartAvailability({
+ chart,
+ dataView,
+ isPlainRecord: stateProps.isPlainRecord,
+ });
+ const chartProps = useMemo(() => {
+ return lensVisService
+ ? {
+ ...props,
+ ...stateProps,
+ input$,
+ chart,
+ isChartAvailable,
+ requestParams,
+ lensVisService,
+ }
+ : undefined;
+ }, [chart, input$, isChartAvailable, lensVisService, props, requestParams, stateProps]);
+ const layoutProps = useMemo(
+ () => ({
+ chart,
+ isChartAvailable,
+ hits: stateProps.hits,
+ topPanelHeight: stateProps.topPanelHeight,
+ onTopPanelHeightChange: stateProps.onTopPanelHeightChange,
+ }),
+ [
+ chart,
+ isChartAvailable,
+ stateProps.hits,
+ stateProps.onTopPanelHeightChange,
+ stateProps.topPanelHeight,
+ ]
+ );
+
+ if (!api || !chartProps) {
+ return { isInitialized: false };
+ }
+
+ return {
+ isInitialized: true,
+ api,
+ chartProps,
+ layoutProps,
+ };
+};
diff --git a/src/platform/plugins/shared/unified_histogram/public/index.ts b/src/platform/packages/shared/kbn-unified-histogram/index.ts
similarity index 61%
rename from src/platform/plugins/shared/unified_histogram/public/index.ts
rename to src/platform/packages/shared/kbn-unified-histogram/index.ts
index f79db6ce8a51..0351beb56109 100644
--- a/src/platform/plugins/shared/unified_histogram/public/index.ts
+++ b/src/platform/packages/shared/kbn-unified-histogram/index.ts
@@ -7,27 +7,6 @@
* License v3.0 only", or the "Server Side Public License, v 1".
*/
-import { UnifiedHistogramPublicPlugin } from './plugin';
-
-export type { BreakdownFieldSelectorProps } from './chart/lazy';
-export { UnifiedBreakdownFieldSelector } from './chart/lazy';
-
-export type {
- UnifiedHistogramApi,
- UnifiedHistogramContainerProps,
- UnifiedHistogramCreationOptions,
- UnifiedHistogramState,
- UnifiedHistogramStateOptions,
-} from './container';
-export {
- UnifiedHistogramContainer,
- getChartHidden,
- getTopPanelHeight,
- getBreakdownField,
- setChartHidden,
- setTopPanelHeight,
- setBreakdownField,
-} from './container';
export type {
UnifiedHistogramServices,
UnifiedHistogramChartLoadEvent,
@@ -35,6 +14,29 @@ export type {
UnifiedHistogramVisContext,
} from './types';
export { UnifiedHistogramFetchStatus, UnifiedHistogramExternalVisContextStatus } from './types';
-export { canImportVisContext } from './utils/external_vis_context';
-export const plugin = () => new UnifiedHistogramPublicPlugin();
+export {
+ UnifiedBreakdownFieldSelector,
+ type BreakdownFieldSelectorProps,
+} from './components/chart/lazy';
+export { UnifiedHistogramChart, type UnifiedHistogramChartProps } from './components/chart';
+export { UnifiedHistogramLayout, type UnifiedHistogramLayoutProps } from './components/layout';
+
+export {
+ useUnifiedHistogram,
+ type UseUnifiedHistogramProps,
+ type UnifiedHistogramApi,
+ type UnifiedHistogramPartialLayoutProps,
+} from './hooks/use_unified_histogram';
+
+export type { UnifiedHistogramState } from './services/state_service';
+
+export {
+ getChartHidden,
+ getTopPanelHeight,
+ getBreakdownField,
+ setChartHidden,
+ setTopPanelHeight,
+ setBreakdownField,
+} from './utils/local_storage_utils';
+export { canImportVisContext } from './utils/external_vis_context';
diff --git a/src/platform/plugins/shared/unified_histogram/jest.config.js b/src/platform/packages/shared/kbn-unified-histogram/jest.config.js
similarity index 60%
rename from src/platform/plugins/shared/unified_histogram/jest.config.js
rename to src/platform/packages/shared/kbn-unified-histogram/jest.config.js
index f46df2953298..fd61a6e3ab5d 100644
--- a/src/platform/plugins/shared/unified_histogram/jest.config.js
+++ b/src/platform/packages/shared/kbn-unified-histogram/jest.config.js
@@ -10,11 +10,5 @@
module.exports = {
preset: '@kbn/test',
rootDir: '../../../../..',
- roots: ['/src/platform/plugins/shared/unified_histogram'],
- coverageDirectory:
- '/target/kibana-coverage/jest/src/platform/plugins/shared/unified_histogram',
- coverageReporters: ['text', 'html'],
- collectCoverageFrom: [
- '/src/platform/plugins/shared/unified_histogram/{common,public,server}/**/*.{ts,tsx}',
- ],
+ roots: ['/src/platform/packages/shared/kbn-unified-histogram'],
};
diff --git a/src/platform/packages/shared/kbn-unified-histogram/kibana.jsonc b/src/platform/packages/shared/kbn-unified-histogram/kibana.jsonc
new file mode 100644
index 000000000000..883a1bff3650
--- /dev/null
+++ b/src/platform/packages/shared/kbn-unified-histogram/kibana.jsonc
@@ -0,0 +1,8 @@
+{
+ "type": "shared-browser",
+ "id": "@kbn/unified-histogram",
+ "owner": "@elastic/kibana-data-discovery",
+ "group": "platform",
+ "visibility": "shared",
+ "description": "Components for the Discover histogram chart"
+}
diff --git a/src/platform/plugins/shared/unified_histogram/public/mocks.ts b/src/platform/packages/shared/kbn-unified-histogram/mocks.ts
similarity index 92%
rename from src/platform/plugins/shared/unified_histogram/public/mocks.ts
rename to src/platform/packages/shared/kbn-unified-histogram/mocks.ts
index 73d7d2bd9301..cdbb1b25788c 100644
--- a/src/platform/plugins/shared/unified_histogram/public/mocks.ts
+++ b/src/platform/packages/shared/kbn-unified-histogram/mocks.ts
@@ -8,7 +8,7 @@
*/
import { Observable } from 'rxjs';
-import type { UnifiedHistogramApi } from './container';
+import { UnifiedHistogramApi } from './hooks/use_unified_histogram';
export const createMockUnifiedHistogramApi = () => {
const api: UnifiedHistogramApi = {
diff --git a/src/platform/packages/shared/kbn-unified-histogram/package.json b/src/platform/packages/shared/kbn-unified-histogram/package.json
new file mode 100644
index 000000000000..3554b00477ec
--- /dev/null
+++ b/src/platform/packages/shared/kbn-unified-histogram/package.json
@@ -0,0 +1,6 @@
+{
+ "name": "@kbn/unified-histogram",
+ "private": true,
+ "version": "1.0.0",
+ "license": "Elastic License 2.0 OR AGPL-3.0-only OR SSPL-1.0"
+}
\ No newline at end of file
diff --git a/src/platform/plugins/shared/unified_histogram/public/services/lens_vis_service.attributes.test.ts b/src/platform/packages/shared/kbn-unified-histogram/services/lens_vis_service.attributes.test.ts
similarity index 100%
rename from src/platform/plugins/shared/unified_histogram/public/services/lens_vis_service.attributes.test.ts
rename to src/platform/packages/shared/kbn-unified-histogram/services/lens_vis_service.attributes.test.ts
diff --git a/src/platform/plugins/shared/unified_histogram/public/services/lens_vis_service.suggestions.test.ts b/src/platform/packages/shared/kbn-unified-histogram/services/lens_vis_service.suggestions.test.ts
similarity index 100%
rename from src/platform/plugins/shared/unified_histogram/public/services/lens_vis_service.suggestions.test.ts
rename to src/platform/packages/shared/kbn-unified-histogram/services/lens_vis_service.suggestions.test.ts
diff --git a/src/platform/plugins/shared/unified_histogram/public/services/lens_vis_service.ts b/src/platform/packages/shared/kbn-unified-histogram/services/lens_vis_service.ts
similarity index 99%
rename from src/platform/plugins/shared/unified_histogram/public/services/lens_vis_service.ts
rename to src/platform/packages/shared/kbn-unified-histogram/services/lens_vis_service.ts
index 010d90bc26ee..eaf6c479884a 100644
--- a/src/platform/plugins/shared/unified_histogram/public/services/lens_vis_service.ts
+++ b/src/platform/packages/shared/kbn-unified-histogram/services/lens_vis_service.ts
@@ -34,8 +34,8 @@ import {
mapVisToChartType,
computeInterval,
} from '@kbn/visualization-utils';
-import { LegendSize } from '@kbn/visualizations-plugin/public';
-import { XYConfiguration } from '@kbn/visualizations-plugin/common';
+import type { LegendSize } from '@kbn/visualizations-plugin/public';
+import type { XYConfiguration } from '@kbn/visualizations-plugin/common';
import type { Datatable, DatatableColumn } from '@kbn/expressions-plugin/common';
import type { DataPublicPluginStart } from '@kbn/data-plugin/public';
import { fieldSupportsBreakdown } from '@kbn/field-utils';
@@ -413,6 +413,7 @@ export class LensVisService {
},
};
+ const legendSize: `${LegendSize.EXTRA_LARGE}` = 'xlarge';
const visualizationState = {
layers: [
{
@@ -435,7 +436,7 @@ export class LensVisService {
legend: {
isVisible: true,
position: 'right',
- legendSize: LegendSize.EXTRA_LARGE,
+ legendSize,
shouldTruncate: false,
},
preferredSeriesType: 'bar_stacked',
diff --git a/src/platform/plugins/shared/unified_histogram/public/container/services/state_service.test.ts b/src/platform/packages/shared/kbn-unified-histogram/services/state_service.test.ts
similarity index 97%
rename from src/platform/plugins/shared/unified_histogram/public/container/services/state_service.test.ts
rename to src/platform/packages/shared/kbn-unified-histogram/services/state_service.test.ts
index 5c3024eef7dd..997202aa96e6 100644
--- a/src/platform/plugins/shared/unified_histogram/public/container/services/state_service.test.ts
+++ b/src/platform/packages/shared/kbn-unified-histogram/services/state_service.test.ts
@@ -8,9 +8,9 @@
*/
import { RequestAdapter } from '@kbn/inspector-plugin/common';
-import { UnifiedHistogramFetchStatus } from '../..';
-import { unifiedHistogramServicesMock } from '../../__mocks__/services';
-import { lensAdaptersMock } from '../../__mocks__/lens_adapters';
+import { UnifiedHistogramFetchStatus } from '..';
+import { unifiedHistogramServicesMock } from '../__mocks__/services';
+import { lensAdaptersMock } from '../__mocks__/lens_adapters';
import {
getChartHidden,
getTopPanelHeight,
diff --git a/src/platform/plugins/shared/unified_histogram/public/container/services/state_service.ts b/src/platform/packages/shared/kbn-unified-histogram/services/state_service.ts
similarity index 97%
rename from src/platform/plugins/shared/unified_histogram/public/container/services/state_service.ts
rename to src/platform/packages/shared/kbn-unified-histogram/services/state_service.ts
index cdca02396e3a..188b736cfec9 100644
--- a/src/platform/plugins/shared/unified_histogram/public/container/services/state_service.ts
+++ b/src/platform/packages/shared/kbn-unified-histogram/services/state_service.ts
@@ -10,15 +10,15 @@
import type { RequestAdapter } from '@kbn/inspector-plugin/common';
import { BehaviorSubject, Observable } from 'rxjs';
import { PublishingSubject } from '@kbn/presentation-publishing';
-import { UnifiedHistogramFetchStatus } from '../..';
-import type { UnifiedHistogramServices, UnifiedHistogramChartLoadEvent } from '../../types';
+import { UnifiedHistogramFetchStatus } from '..';
+import type { UnifiedHistogramServices, UnifiedHistogramChartLoadEvent } from '../types';
import {
getChartHidden,
getTopPanelHeight,
setChartHidden,
setTopPanelHeight,
} from '../utils/local_storage_utils';
-import type { UnifiedHistogramSuggestionContext } from '../../types';
+import type { UnifiedHistogramSuggestionContext } from '../types';
/**
* The current state of the container
diff --git a/src/platform/plugins/shared/unified_histogram/tsconfig.json b/src/platform/packages/shared/kbn-unified-histogram/tsconfig.json
similarity index 84%
rename from src/platform/plugins/shared/unified_histogram/tsconfig.json
rename to src/platform/packages/shared/kbn-unified-histogram/tsconfig.json
index e1ae051c5fba..f5c8153c06b9 100644
--- a/src/platform/plugins/shared/unified_histogram/tsconfig.json
+++ b/src/platform/packages/shared/kbn-unified-histogram/tsconfig.json
@@ -2,40 +2,39 @@
"extends": "../../../../../tsconfig.base.json",
"compilerOptions": {
"outDir": "target/types",
+ "types": ["jest", "node", "react", "@emotion/react/types/css-prop"]
},
- "include": [ "../../../../../typings/**/*", "common/**/*", "public/**/*", "server/**/*"],
+ "include": ["**/*.ts", "**/*.tsx"],
+ "exclude": ["target/**/*"],
"kbn_references": [
- "@kbn/core",
- "@kbn/data-plugin",
"@kbn/data-views-plugin",
- "@kbn/lens-plugin",
- "@kbn/field-formats-plugin",
- "@kbn/inspector-plugin",
"@kbn/expressions-plugin",
- "@kbn/test-jest-helpers",
- "@kbn/i18n",
- "@kbn/es-query",
- "@kbn/core-ui-settings-browser",
- "@kbn/datemath",
- "@kbn/core-ui-settings-browser-mocks",
- "@kbn/shared-ux-utility",
- "@kbn/ui-actions-plugin",
- "@kbn/kibana-utils-plugin",
- "@kbn/visualizations-plugin",
- "@kbn/resizable-layout",
- "@kbn/shared-ux-button-toolbar",
- "@kbn/calculate-width-from-char-count",
- "@kbn/lens-embeddable-utils",
- "@kbn/i18n-react",
+ "@kbn/lens-plugin",
+ "@kbn/data-plugin",
+ "@kbn/field-formats-plugin",
+ "@kbn/data-view-utils",
"@kbn/field-utils",
"@kbn/esql-utils",
- "@kbn/discover-utils",
- "@kbn/visualization-utils",
- "@kbn/search-types",
+ "@kbn/i18n",
+ "@kbn/test-jest-helpers",
+ "@kbn/core",
+ "@kbn/shared-ux-button-toolbar",
+ "@kbn/es-query",
"@kbn/presentation-publishing",
- "@kbn/data-view-utils",
- ],
- "exclude": [
- "target/**/*",
+ "@kbn/inspector-plugin",
+ "@kbn/search-types",
+ "@kbn/discover-utils",
+ "@kbn/ui-actions-plugin",
+ "@kbn/core-ui-settings-browser-mocks",
+ "@kbn/core-ui-settings-browser",
+ "@kbn/datemath",
+ "@kbn/shared-ux-utility",
+ "@kbn/i18n-react",
+ "@kbn/calculate-width-from-char-count",
+ "@kbn/resizable-layout",
+ "@kbn/visualization-utils",
+ "@kbn/visualizations-plugin",
+ "@kbn/kibana-utils-plugin",
+ "@kbn/lens-embeddable-utils"
]
}
diff --git a/src/platform/plugins/shared/unified_histogram/public/types.ts b/src/platform/packages/shared/kbn-unified-histogram/types.ts
similarity index 100%
rename from src/platform/plugins/shared/unified_histogram/public/types.ts
rename to src/platform/packages/shared/kbn-unified-histogram/types.ts
diff --git a/src/platform/plugins/shared/unified_histogram/public/utils/__snapshots__/external_vis_context.test.ts.snap b/src/platform/packages/shared/kbn-unified-histogram/utils/__snapshots__/external_vis_context.test.ts.snap
similarity index 100%
rename from src/platform/plugins/shared/unified_histogram/public/utils/__snapshots__/external_vis_context.test.ts.snap
rename to src/platform/packages/shared/kbn-unified-histogram/utils/__snapshots__/external_vis_context.test.ts.snap
diff --git a/src/platform/plugins/shared/unified_histogram/public/utils/external_vis_context.test.ts b/src/platform/packages/shared/kbn-unified-histogram/utils/external_vis_context.test.ts
similarity index 100%
rename from src/platform/plugins/shared/unified_histogram/public/utils/external_vis_context.test.ts
rename to src/platform/packages/shared/kbn-unified-histogram/utils/external_vis_context.test.ts
diff --git a/src/platform/plugins/shared/unified_histogram/public/utils/external_vis_context.ts b/src/platform/packages/shared/kbn-unified-histogram/utils/external_vis_context.ts
similarity index 100%
rename from src/platform/plugins/shared/unified_histogram/public/utils/external_vis_context.ts
rename to src/platform/packages/shared/kbn-unified-histogram/utils/external_vis_context.ts
diff --git a/src/platform/plugins/shared/unified_histogram/public/utils/lens_vis_from_table.ts b/src/platform/packages/shared/kbn-unified-histogram/utils/lens_vis_from_table.ts
similarity index 100%
rename from src/platform/plugins/shared/unified_histogram/public/utils/lens_vis_from_table.ts
rename to src/platform/packages/shared/kbn-unified-histogram/utils/lens_vis_from_table.ts
diff --git a/src/platform/plugins/shared/unified_histogram/public/container/utils/local_storage_utils.test.ts b/src/platform/packages/shared/kbn-unified-histogram/utils/local_storage_utils.test.ts
similarity index 100%
rename from src/platform/plugins/shared/unified_histogram/public/container/utils/local_storage_utils.test.ts
rename to src/platform/packages/shared/kbn-unified-histogram/utils/local_storage_utils.test.ts
diff --git a/src/platform/plugins/shared/unified_histogram/public/container/utils/local_storage_utils.ts b/src/platform/packages/shared/kbn-unified-histogram/utils/local_storage_utils.ts
similarity index 97%
rename from src/platform/plugins/shared/unified_histogram/public/container/utils/local_storage_utils.ts
rename to src/platform/packages/shared/kbn-unified-histogram/utils/local_storage_utils.ts
index 5ba77c6dbeaf..3d91796f0329 100644
--- a/src/platform/plugins/shared/unified_histogram/public/container/utils/local_storage_utils.ts
+++ b/src/platform/packages/shared/kbn-unified-histogram/utils/local_storage_utils.ts
@@ -7,7 +7,7 @@
* License v3.0 only", or the "Server Side Public License, v 1".
*/
-import { Storage } from '@kbn/kibana-utils-plugin/public';
+import type { Storage } from '@kbn/kibana-utils-plugin/public';
export const CHART_HIDDEN_KEY = 'chartHidden';
export const HISTOGRAM_HEIGHT_KEY = 'histogramHeight';
diff --git a/src/platform/plugins/shared/unified_histogram/public/container/utils/state_selectors.ts b/src/platform/packages/shared/kbn-unified-histogram/utils/state_selectors.ts
similarity index 100%
rename from src/platform/plugins/shared/unified_histogram/public/container/utils/state_selectors.ts
rename to src/platform/packages/shared/kbn-unified-histogram/utils/state_selectors.ts
diff --git a/src/platform/plugins/shared/discover/kibana.jsonc b/src/platform/plugins/shared/discover/kibana.jsonc
index f9b2ea14cbc6..b3d4080633a4 100644
--- a/src/platform/plugins/shared/discover/kibana.jsonc
+++ b/src/platform/plugins/shared/discover/kibana.jsonc
@@ -30,7 +30,6 @@
"expressions",
"unifiedDocViewer",
"unifiedSearch",
- "unifiedHistogram",
"contentManagement",
"discoverShared"
],
diff --git a/src/platform/plugins/shared/discover/public/__mocks__/discover_state.mock.ts b/src/platform/plugins/shared/discover/public/__mocks__/discover_state.mock.ts
index bc1f4697b12f..4cd4c47421aa 100644
--- a/src/platform/plugins/shared/discover/public/__mocks__/discover_state.mock.ts
+++ b/src/platform/plugins/shared/discover/public/__mocks__/discover_state.mock.ts
@@ -17,12 +17,14 @@ import type { RuntimeStateManager } from '../application/main/state_management/r
import {
createInternalStateStore,
createRuntimeStateManager,
+ selectTabRuntimeState,
} from '../application/main/state_management/redux';
import type { DiscoverServices, HistoryLocationState } from '../build_services';
import type { IKbnUrlStateStorage } from '@kbn/kibana-utils-plugin/public';
import { createKbnUrlStateStorage, withNotifyOnErrors } from '@kbn/kibana-utils-plugin/public';
import type { History } from 'history';
import type { DiscoverCustomizationContext } from '../customizations';
+import { createCustomizationService } from '../customizations/customization_service';
export function getDiscoverStateMock({
isTimeBased = true,
@@ -71,6 +73,15 @@ export function getDiscoverStateMock({
internalState,
runtimeStateManager,
});
+ const tabRuntimeState = selectTabRuntimeState(
+ runtimeStateManager,
+ internalState.getState().tabs.unsafeCurrentId
+ );
+ tabRuntimeState.customizationService$.next({
+ ...createCustomizationService(),
+ cleanup: async () => {},
+ });
+ tabRuntimeState.stateContainer$.next(container);
if (savedSearch !== false) {
container.savedSearchState.set(
savedSearch ? savedSearch : isTimeBased ? savedSearchMockWithTimeField : savedSearchMock
diff --git a/src/platform/plugins/shared/discover/public/__mocks__/services.ts b/src/platform/plugins/shared/discover/public/__mocks__/services.ts
index 4ed0dbf98048..f67c46f6d694 100644
--- a/src/platform/plugins/shared/discover/public/__mocks__/services.ts
+++ b/src/platform/plugins/shared/discover/public/__mocks__/services.ts
@@ -63,6 +63,9 @@ export function createDiscoverServicesMock(): DiscoverServices {
dataPlugin.query.timefilter.timefilter.getTime = jest.fn(() => {
return { from: 'now-15m', to: 'now' };
});
+ dataPlugin.query.timefilter.timefilter.getTimeDefaults = jest.fn(() => {
+ return { from: 'now-15m', to: 'now' };
+ });
dataPlugin.query.timefilter.timefilter.getRefreshInterval = jest.fn(() => {
return { pause: true, value: 1000 };
});
diff --git a/src/platform/plugins/shared/discover/public/application/main/components/chart/chart_portals_renderer.tsx b/src/platform/plugins/shared/discover/public/application/main/components/chart/chart_portals_renderer.tsx
new file mode 100644
index 000000000000..535dc913335c
--- /dev/null
+++ b/src/platform/plugins/shared/discover/public/application/main/components/chart/chart_portals_renderer.tsx
@@ -0,0 +1,169 @@
+/*
+ * 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", the "GNU Affero General Public License v3.0 only", and the "Server Side
+ * Public License v 1"; you may not use this file except in compliance with, at
+ * your election, the "Elastic License 2.0", the "GNU Affero General Public
+ * License v3.0 only", or the "Server Side Public License, v 1".
+ */
+
+import React, { type PropsWithChildren, useCallback, useEffect, useRef } from 'react';
+import { type HtmlPortalNode, InPortal, createHtmlPortalNode } from 'react-reverse-portal';
+import { UnifiedHistogramChart, useUnifiedHistogram } from '@kbn/unified-histogram';
+import { DiscoverCustomizationProvider } from '../../../../customizations';
+import {
+ useInternalStateSelector,
+ type RuntimeStateManager,
+ selectTabRuntimeState,
+ useRuntimeState,
+ CurrentTabProvider,
+ RuntimeStateProvider,
+ useCurrentTabSelector,
+} from '../../state_management/redux';
+import type { DiscoverMainContentProps } from '../layout/discover_main_content';
+import { DiscoverMainProvider } from '../../state_management/discover_state_provider';
+import type { DiscoverStateContainer } from '../../state_management/discover_state';
+import { useIsEsqlMode } from '../../hooks/use_is_esql_mode';
+import { useDiscoverHistogram } from './use_discover_histogram';
+
+export type ChartPortalNode = HtmlPortalNode;
+export type ChartPortalNodes = Record;
+
+export const ChartPortalsRenderer = ({
+ runtimeStateManager,
+ children,
+}: PropsWithChildren<{
+ runtimeStateManager: RuntimeStateManager;
+}>) => {
+ const allTabIds = useInternalStateSelector((state) => state.tabs.allIds);
+ const currentTabId = useInternalStateSelector((state) => state.tabs.unsafeCurrentId);
+ const chartPortalNodes = useRef({});
+
+ chartPortalNodes.current = updatePortals(chartPortalNodes.current, allTabIds);
+
+ return (
+ <>
+ {Object.keys(chartPortalNodes.current).map((tabId) => {
+ return (
+
+
+
+ );
+ })}
+
+ {children}
+
+ >
+ );
+};
+
+const updatePortals = (portals: ChartPortalNodes, tabsIds: string[]) =>
+ tabsIds.reduce(
+ (acc, tabId) => ({
+ ...acc,
+ [tabId]: portals[tabId] || createHtmlPortalNode({ attributes: { class: 'eui-fullHeight' } }),
+ }),
+ {}
+ );
+
+interface UnifiedHistogramGuardProps {
+ tabId: string;
+ runtimeStateManager: RuntimeStateManager;
+ panelsToggle?: DiscoverMainContentProps['panelsToggle'];
+}
+
+const UnifiedHistogramGuard = ({
+ tabId,
+ runtimeStateManager,
+ panelsToggle,
+}: UnifiedHistogramGuardProps) => {
+ const isSelected = useInternalStateSelector((state) => state.tabs.unsafeCurrentId === tabId);
+ const currentTabRuntimeState = selectTabRuntimeState(runtimeStateManager, tabId);
+ const currentCustomizationService = useRuntimeState(currentTabRuntimeState.customizationService$);
+ const currentStateContainer = useRuntimeState(currentTabRuntimeState.stateContainer$);
+ const currentDataView = useRuntimeState(currentTabRuntimeState.currentDataView$);
+ const adHocDataViews = useRuntimeState(runtimeStateManager.adHocDataViews$);
+ const isInitialized = useRef(false);
+
+ if (
+ (!isSelected && !isInitialized.current) ||
+ !currentCustomizationService ||
+ !currentStateContainer ||
+ !currentDataView ||
+ !currentTabRuntimeState
+ ) {
+ return null;
+ }
+
+ isInitialized.current = true;
+
+ return (
+
+
+
+
+
+
+
+
+
+ );
+};
+
+type UnifiedHistogramChartProps = Pick & {
+ stateContainer: DiscoverStateContainer;
+};
+
+const UnifiedHistogramChartWrapper = ({
+ stateContainer,
+ panelsToggle,
+}: UnifiedHistogramChartProps) => {
+ const { setUnifiedHistogramApi, ...unifiedHistogramProps } = useDiscoverHistogram(stateContainer);
+ const unifiedHistogram = useUnifiedHistogram(unifiedHistogramProps);
+
+ useEffect(() => {
+ if (unifiedHistogram.isInitialized) {
+ setUnifiedHistogramApi(unifiedHistogram.api);
+ }
+ }, [setUnifiedHistogramApi, unifiedHistogram.api, unifiedHistogram.isInitialized]);
+
+ const currentTabId = useCurrentTabSelector((tab) => tab.id);
+
+ useEffect(() => {
+ if (unifiedHistogram.layoutProps) {
+ const currentTabRuntimeState = selectTabRuntimeState(
+ stateContainer.runtimeStateManager,
+ currentTabId
+ );
+ currentTabRuntimeState.unifiedHistogramLayoutProps$.next(unifiedHistogram.layoutProps);
+ }
+ }, [currentTabId, stateContainer.runtimeStateManager, unifiedHistogram.layoutProps]);
+
+ const isEsqlMode = useIsEsqlMode();
+ const renderCustomChartToggleActions = useCallback(
+ () =>
+ React.isValidElement(panelsToggle)
+ ? React.cloneElement(panelsToggle, { renderedFor: 'histogram' })
+ : panelsToggle,
+ [panelsToggle]
+ );
+
+ // Initialized when the first search has been requested or
+ // when in ES|QL mode since search sessions are not supported
+ if (!unifiedHistogram.isInitialized || (!unifiedHistogramProps.searchSessionId && !isEsqlMode)) {
+ return null;
+ }
+
+ return (
+
+ );
+};
diff --git a/src/platform/plugins/shared/unified_histogram/public/layout/index.ts b/src/platform/plugins/shared/discover/public/application/main/components/chart/index.ts
similarity index 80%
rename from src/platform/plugins/shared/unified_histogram/public/layout/index.ts
rename to src/platform/plugins/shared/discover/public/application/main/components/chart/index.ts
index dd8f79cc2e4a..44a874e594e6 100644
--- a/src/platform/plugins/shared/unified_histogram/public/layout/index.ts
+++ b/src/platform/plugins/shared/discover/public/application/main/components/chart/index.ts
@@ -7,5 +7,4 @@
* License v3.0 only", or the "Server Side Public License, v 1".
*/
-export type { UnifiedHistogramLayoutProps } from './layout';
-export { UnifiedHistogramLayout } from './layout';
+export { type ChartPortalNode, ChartPortalsRenderer } from './chart_portals_renderer';
diff --git a/src/platform/plugins/shared/discover/public/application/main/components/layout/use_discover_histogram.test.tsx b/src/platform/plugins/shared/discover/public/application/main/components/chart/use_discover_histogram.test.tsx
similarity index 87%
rename from src/platform/plugins/shared/discover/public/application/main/components/layout/use_discover_histogram.test.tsx
rename to src/platform/plugins/shared/discover/public/application/main/components/chart/use_discover_histogram.test.tsx
index 54246d64f264..96d1414e66ff 100644
--- a/src/platform/plugins/shared/discover/public/application/main/components/layout/use_discover_histogram.test.tsx
+++ b/src/platform/plugins/shared/discover/public/application/main/components/chart/use_discover_histogram.test.tsx
@@ -7,7 +7,6 @@
* License v3.0 only", or the "Server Side Public License, v 1".
*/
-import type { ReactElement } from 'react';
import React from 'react';
import type { AggregateQuery, Query } from '@kbn/es-query';
import { renderHook, act } from '@testing-library/react';
@@ -15,17 +14,15 @@ import { BehaviorSubject, Subject } from 'rxjs';
import { FetchStatus } from '../../../types';
import type { DiscoverStateContainer } from '../../state_management/discover_state';
import { dataPluginMock } from '@kbn/data-plugin/public/mocks';
-import type { UseDiscoverHistogramProps } from './use_discover_histogram';
import { useDiscoverHistogram } from './use_discover_histogram';
import { setTimeout } from 'timers/promises';
import { getDiscoverStateMock } from '../../../../__mocks__/discover_state.mock';
import { DiscoverMainProvider } from '../../state_management/discover_state_provider';
import { RequestAdapter } from '@kbn/inspector-plugin/public';
-import type { UnifiedHistogramState } from '@kbn/unified-histogram-plugin/public';
-import { UnifiedHistogramFetchStatus } from '@kbn/unified-histogram-plugin/public';
-import { createMockUnifiedHistogramApi } from '@kbn/unified-histogram-plugin/public/mocks';
+import type { UnifiedHistogramState } from '@kbn/unified-histogram';
+import { UnifiedHistogramFetchStatus } from '@kbn/unified-histogram';
+import { createMockUnifiedHistogramApi } from '@kbn/unified-histogram/mocks';
import { checkHitCount, sendErrorTo } from '../../hooks/use_saved_search_messages';
-import type { InspectorAdapters } from '../../hooks/use_inspector';
import type { UnifiedHistogramCustomization } from '../../../../customizations/customization_types/histogram_customization';
import { useDiscoverCustomization } from '../../../../customizations';
import type { DiscoverCustomizationId } from '../../../../customizations/customization_service';
@@ -111,44 +108,26 @@ describe('useDiscoverHistogram', () => {
return stateContainer;
};
- const renderUseDiscoverHistogram = async ({
- stateContainer = getStateContainer(),
- inspectorAdapters = { requests: new RequestAdapter() },
- hideChart = false,
- }: {
- stateContainer?: DiscoverStateContainer;
- inspectorAdapters?: InspectorAdapters;
- hideChart?: boolean;
- } = {}) => {
- const initialProps = {
- stateContainer,
- inspectorAdapters,
- hideChart,
- };
-
+ const renderUseDiscoverHistogram = async (
+ stateContainer: DiscoverStateContainer = getStateContainer()
+ ) => {
const Wrapper = ({ children }: React.PropsWithChildren) => (
- {children as ReactElement}
+ {children}
);
- const hook = renderHook(
- (props: UseDiscoverHistogramProps) => {
- return useDiscoverHistogram(props);
- },
- {
- wrapper: Wrapper,
- initialProps,
- }
- );
+ const hook = renderHook(() => useDiscoverHistogram(stateContainer), {
+ wrapper: Wrapper,
+ });
await act(() => setTimeout(0));
- return { hook, initialProps };
+ return { hook };
};
beforeEach(() => {
@@ -169,9 +148,9 @@ describe('useDiscoverHistogram', () => {
});
describe('initialization', () => {
- it('should return the expected parameters from getCreationOptions', async () => {
+ it('should return the expected parameters', async () => {
const { hook } = await renderUseDiscoverHistogram();
- const params = hook.result.current.getCreationOptions();
+ const params = hook.result.current;
expect(params?.localStorageKeyPrefix).toBe('discover');
expect(Object.keys(params?.initialState ?? {})).toEqual([
'chartHidden',
@@ -200,7 +179,7 @@ describe('useDiscoverHistogram', () => {
const api = createMockUnifiedHistogramApi();
jest.spyOn(api.state$, 'subscribe');
act(() => {
- hook.result.current.ref(api);
+ hook.result.current.setUnifiedHistogramApi(api);
});
expect(api.state$.subscribe).toHaveBeenCalledTimes(2);
});
@@ -208,7 +187,8 @@ describe('useDiscoverHistogram', () => {
it('should sync Unified Histogram state with the state container', async () => {
const stateContainer = getStateContainer();
const inspectorAdapters = { requests: new RequestAdapter(), lensRequests: undefined };
- const { hook } = await renderUseDiscoverHistogram({ stateContainer, inspectorAdapters });
+ stateContainer.dataState.inspectorAdapters = inspectorAdapters;
+ const { hook } = await renderUseDiscoverHistogram(stateContainer);
const lensRequestAdapter = new RequestAdapter();
const state = {
timeInterval: '1m',
@@ -219,7 +199,7 @@ describe('useDiscoverHistogram', () => {
const api = createMockUnifiedHistogramApi();
api.state$ = new BehaviorSubject({ ...state, lensRequestAdapter });
act(() => {
- hook.result.current.ref(api);
+ hook.result.current.setUnifiedHistogramApi(api);
});
expect(inspectorAdapters.lensRequests).toBe(lensRequestAdapter);
expect(stateContainer.appState.update).toHaveBeenCalledWith({
@@ -230,7 +210,7 @@ describe('useDiscoverHistogram', () => {
it('should not sync Unified Histogram state with the state container if there are no changes', async () => {
const stateContainer = getStateContainer();
- const { hook } = await renderUseDiscoverHistogram({ stateContainer });
+ const { hook } = await renderUseDiscoverHistogram(stateContainer);
const containerState = stateContainer.appState.getState();
const state = {
timeInterval: containerState.interval,
@@ -241,14 +221,14 @@ describe('useDiscoverHistogram', () => {
const api = createMockUnifiedHistogramApi();
api.state$ = new BehaviorSubject(state);
act(() => {
- hook.result.current.ref(api);
+ hook.result.current.setUnifiedHistogramApi(api);
});
expect(stateContainer.appState.update).not.toHaveBeenCalled();
});
it('should sync the state container state with Unified Histogram', async () => {
const stateContainer = getStateContainer();
- const { hook } = await renderUseDiscoverHistogram({ stateContainer });
+ const { hook } = await renderUseDiscoverHistogram(stateContainer);
const api = createMockUnifiedHistogramApi();
let params: Partial = {};
api.setTotalHits = jest.fn((p) => {
@@ -261,7 +241,7 @@ describe('useDiscoverHistogram', () => {
params = { ...params, timeInterval };
});
act(() => {
- hook.result.current.ref(api);
+ hook.result.current.setUnifiedHistogramApi(api);
});
stateContainer.appState.update({ hideChart: true, interval: '1m' });
expect(api.setTotalHits).not.toHaveBeenCalled();
@@ -272,7 +252,7 @@ describe('useDiscoverHistogram', () => {
it('should exclude totalHitsStatus and totalHitsResult from Unified Histogram state updates', async () => {
const stateContainer = getStateContainer();
- const { hook } = await renderUseDiscoverHistogram({ stateContainer });
+ const { hook } = await renderUseDiscoverHistogram(stateContainer);
const containerState = stateContainer.appState.getState();
const state = {
timeInterval: containerState.interval,
@@ -288,7 +268,7 @@ describe('useDiscoverHistogram', () => {
const subject$ = new BehaviorSubject(state);
api.state$ = subject$;
act(() => {
- hook.result.current.ref(api);
+ hook.result.current.setUnifiedHistogramApi(api);
});
stateContainer.appState.update({ hideChart: true });
expect(Object.keys(params ?? {})).toEqual(['chartHidden']);
@@ -306,7 +286,7 @@ describe('useDiscoverHistogram', () => {
it('should update total hits when the total hits state changes', async () => {
const stateContainer = getStateContainer();
- const { hook } = await renderUseDiscoverHistogram({ stateContainer });
+ const { hook } = await renderUseDiscoverHistogram(stateContainer);
const containerState = stateContainer.appState.getState();
const state = {
timeInterval: containerState.interval,
@@ -325,7 +305,7 @@ describe('useDiscoverHistogram', () => {
result: 100,
});
act(() => {
- hook.result.current.ref(api);
+ hook.result.current.setUnifiedHistogramApi(api);
});
expect(stateContainer.dataState.data$.totalHits$.value).toEqual({
fetchStatus: FetchStatus.COMPLETE,
@@ -349,7 +329,7 @@ describe('useDiscoverHistogram', () => {
mockData.query.getState = () => mockQueryState;
const stateContainer = getStateContainer();
- const { hook } = await renderUseDiscoverHistogram({ stateContainer });
+ const { hook } = await renderUseDiscoverHistogram(stateContainer);
const containerState = stateContainer.appState.getState();
const error = new Error('test');
const state = {
@@ -369,7 +349,7 @@ describe('useDiscoverHistogram', () => {
error,
});
act(() => {
- hook.result.current.ref(api);
+ hook.result.current.setUnifiedHistogramApi(api);
});
expect(sendErrorTo).toHaveBeenCalledWith(stateContainer.dataState.data$.totalHits$);
expect(stateContainer.dataState.data$.totalHits$.value).toEqual({
@@ -384,7 +364,7 @@ describe('useDiscoverHistogram', () => {
const stateContainer = getStateContainer();
stateContainer.appState.update({ query: { esql: 'from *' } });
stateContainer.dataState.fetchChart$ = fetch$;
- const { hook } = await renderUseDiscoverHistogram({ stateContainer });
+ const { hook } = await renderUseDiscoverHistogram(stateContainer);
act(() => {
fetch$.next();
});
@@ -404,7 +384,7 @@ describe('useDiscoverHistogram', () => {
},
})
);
- const { hook } = await renderUseDiscoverHistogram({ stateContainer });
+ const { hook } = await renderUseDiscoverHistogram(stateContainer);
act(() => {
fetch$.next();
});
@@ -418,10 +398,10 @@ describe('useDiscoverHistogram', () => {
const savedSearchFetch$ = new Subject();
const stateContainer = getStateContainer();
stateContainer.dataState.fetchChart$ = savedSearchFetch$;
- const { hook } = await renderUseDiscoverHistogram({ stateContainer });
+ const { hook } = await renderUseDiscoverHistogram(stateContainer);
const api = createMockUnifiedHistogramApi();
act(() => {
- hook.result.current.ref(api);
+ hook.result.current.setUnifiedHistogramApi(api);
});
expect(api.fetch).not.toHaveBeenCalled();
act(() => {
@@ -435,7 +415,7 @@ describe('useDiscoverHistogram', () => {
test('should use custom values provided by customization fwk ', async () => {
mockUseCustomizations = true;
const stateContainer = getStateContainer();
- const { hook } = await renderUseDiscoverHistogram({ stateContainer });
+ const { hook } = await renderUseDiscoverHistogram(stateContainer);
expect(hook.result.current.onFilter).toEqual(mockHistogramCustomization.onFilter);
expect(hook.result.current.onBrushEnd).toEqual(mockHistogramCustomization.onBrushEnd);
diff --git a/src/platform/plugins/shared/discover/public/application/main/components/layout/use_discover_histogram.ts b/src/platform/plugins/shared/discover/public/application/main/components/chart/use_discover_histogram.ts
similarity index 86%
rename from src/platform/plugins/shared/discover/public/application/main/components/layout/use_discover_histogram.ts
rename to src/platform/plugins/shared/discover/public/application/main/components/chart/use_discover_histogram.ts
index 8f28ef2f0dc1..b80f77b6b242 100644
--- a/src/platform/plugins/shared/discover/public/application/main/components/layout/use_discover_histogram.ts
+++ b/src/platform/plugins/shared/discover/public/application/main/components/chart/use_discover_histogram.ts
@@ -10,16 +10,15 @@
import { useQuerySubscriber } from '@kbn/unified-field-list/src/hooks/use_query_subscriber';
import type {
UnifiedHistogramApi,
- UnifiedHistogramContainerProps,
- UnifiedHistogramCreationOptions,
UnifiedHistogramState,
UnifiedHistogramVisContext,
-} from '@kbn/unified-histogram-plugin/public';
+ UseUnifiedHistogramProps,
+} from '@kbn/unified-histogram';
import {
canImportVisContext,
UnifiedHistogramExternalVisContextStatus,
UnifiedHistogramFetchStatus,
-} from '@kbn/unified-histogram-plugin/public';
+} from '@kbn/unified-histogram';
import { isEqual } from 'lodash';
import { useCallback, useEffect, useMemo, useState } from 'react';
import type { Observable } from 'rxjs';
@@ -43,7 +42,6 @@ import { ESQL_TABLE_TYPE } from '@kbn/data-plugin/common';
import { useDiscoverCustomization } from '../../../../customizations';
import { useDiscoverServices } from '../../../../hooks/use_discover_services';
import { FetchStatus } from '../../../types';
-import type { InspectorAdapters } from '../../hooks/use_inspector';
import { checkHitCount, sendErrorTo } from '../../hooks/use_saved_search_messages';
import type { DiscoverStateContainer } from '../../state_management/discover_state';
import { addLog } from '../../../../utils/add_log';
@@ -65,25 +63,15 @@ import {
const EMPTY_ESQL_COLUMNS: DatatableColumn[] = [];
const EMPTY_FILTERS: Filter[] = [];
-export interface UseDiscoverHistogramProps {
- stateContainer: DiscoverStateContainer;
- inspectorAdapters: InspectorAdapters;
- hideChart: boolean | undefined;
-}
-
-export const useDiscoverHistogram = ({
- stateContainer,
- inspectorAdapters,
- hideChart,
-}: UseDiscoverHistogramProps): Omit<
- UnifiedHistogramContainerProps,
- 'container' | 'getCreationOptions'
-> & {
- ref: (api: UnifiedHistogramApi | null) => void;
- getCreationOptions: () => UnifiedHistogramCreationOptions;
-} => {
+export const useDiscoverHistogram = (
+ stateContainer: DiscoverStateContainer
+): UseUnifiedHistogramProps & { setUnifiedHistogramApi: (api: UnifiedHistogramApi) => void } => {
const services = useDiscoverServices();
- const { main$, documents$, totalHits$ } = stateContainer.dataState.data$;
+ const {
+ data$: { main$, documents$, totalHits$ },
+ inspectorAdapters,
+ getAbortController,
+ } = stateContainer.dataState;
const savedSearchState = useSavedSearch();
const isEsqlMode = useIsEsqlMode();
@@ -91,53 +79,38 @@ export const useDiscoverHistogram = ({
* API initialization
*/
- const [unifiedHistogram, ref] = useState();
+ const [unifiedHistogramApi, setUnifiedHistogramApi] = useState();
const [isSuggestionLoading, setIsSuggestionLoading] = useState(false);
- const getCreationOptions = useCallback(() => {
- const { hideChart: chartHidden, interval: timeInterval } = stateContainer.appState.getState();
-
- return {
- localStorageKeyPrefix: 'discover',
- disableAutoFetching: true,
- initialState: {
- chartHidden,
- timeInterval,
- totalHitsStatus: UnifiedHistogramFetchStatus.loading,
- totalHitsResult: undefined,
- },
- };
- }, [stateContainer.appState]);
-
/**
* Sync Unified Histogram state with Discover state
*/
useEffect(() => {
- const subscription = createUnifiedHistogramStateObservable(unifiedHistogram?.state$)?.subscribe(
- (changes) => {
- const { lensRequestAdapter, ...stateChanges } = changes;
- const appState = stateContainer.appState.getState();
- const oldState = {
- hideChart: appState.hideChart,
- interval: appState.interval,
- };
- const newState = { ...oldState, ...stateChanges };
+ const subscription = createUnifiedHistogramStateObservable(
+ unifiedHistogramApi?.state$
+ )?.subscribe((changes) => {
+ const { lensRequestAdapter, ...stateChanges } = changes;
+ const appState = stateContainer.appState.getState();
+ const oldState = {
+ hideChart: appState.hideChart,
+ interval: appState.interval,
+ };
+ const newState = { ...oldState, ...stateChanges };
- if ('lensRequestAdapter' in changes) {
- inspectorAdapters.lensRequests = lensRequestAdapter;
- }
-
- if (!isEqual(oldState, newState)) {
- stateContainer.appState.update(newState);
- }
+ if ('lensRequestAdapter' in changes) {
+ inspectorAdapters.lensRequests = lensRequestAdapter;
}
- );
+
+ if (!isEqual(oldState, newState)) {
+ stateContainer.appState.update(newState);
+ }
+ });
return () => {
subscription?.unsubscribe();
};
- }, [inspectorAdapters, stateContainer.appState, unifiedHistogram?.state$]);
+ }, [inspectorAdapters, stateContainer.appState, unifiedHistogramApi?.state$]);
/**
* Sync URL query params with Unified Histogram
@@ -147,11 +120,11 @@ export const useDiscoverHistogram = ({
const subscription = createAppStateObservable(stateContainer.appState.state$).subscribe(
(changes) => {
if ('timeInterval' in changes && changes.timeInterval) {
- unifiedHistogram?.setTimeInterval(changes.timeInterval);
+ unifiedHistogramApi?.setTimeInterval(changes.timeInterval);
}
if ('chartHidden' in changes && typeof changes.chartHidden === 'boolean') {
- unifiedHistogram?.setChartHidden(changes.chartHidden);
+ unifiedHistogramApi?.setChartHidden(changes.chartHidden);
}
}
);
@@ -159,7 +132,7 @@ export const useDiscoverHistogram = ({
return () => {
subscription?.unsubscribe();
};
- }, [stateContainer.appState.state$, unifiedHistogram]);
+ }, [stateContainer.appState.state$, unifiedHistogramApi]);
/**
* Total hits
@@ -168,7 +141,7 @@ export const useDiscoverHistogram = ({
const setTotalHitsError = useMemo(() => sendErrorTo(totalHits$), [totalHits$]);
useEffect(() => {
- const subscription = createTotalHitsObservable(unifiedHistogram?.state$)?.subscribe(
+ const subscription = createTotalHitsObservable(unifiedHistogramApi?.state$)?.subscribe(
({ status, result }) => {
if (isEsqlMode) {
// ignore histogram's total hits updates for ES|QL as Discover manages them during docs fetching
@@ -221,7 +194,7 @@ export const useDiscoverHistogram = ({
totalHits$,
setTotalHitsError,
stateContainer.appState,
- unifiedHistogram?.state$,
+ unifiedHistogramApi?.state$,
]);
/**
@@ -282,7 +255,7 @@ export const useDiscoverHistogram = ({
// Handle unified histogram refetching
useEffect(() => {
- if (!unifiedHistogram) {
+ if (!unifiedHistogramApi) {
return;
}
@@ -297,7 +270,7 @@ export const useDiscoverHistogram = ({
// a refetch anyway and result in multiple unnecessary fetches.
if (isEsqlMode) {
fetchChart$ = merge(
- createCurrentSuggestionObservable(unifiedHistogram.state$).pipe(map(() => 'lens')),
+ createCurrentSuggestionObservable(unifiedHistogramApi.state$).pipe(map(() => 'lens')),
esqlFetchComplete$.pipe(map(() => 'discover'))
).pipe(debounceTime(50));
} else {
@@ -307,13 +280,13 @@ export const useDiscoverHistogram = ({
const subscription = fetchChart$.subscribe((source) => {
if (source === 'discover') addLog('Unified Histogram - Discover refetch');
if (source === 'lens') addLog('Unified Histogram - Lens suggestion refetch');
- unifiedHistogram.fetch();
+ unifiedHistogramApi.fetch();
});
return () => {
subscription.unsubscribe();
};
- }, [isEsqlMode, stateContainer.dataState.fetchChart$, esqlFetchComplete$, unifiedHistogram]);
+ }, [isEsqlMode, stateContainer.dataState.fetchChart$, esqlFetchComplete$, unifiedHistogramApi]);
const dataView = useCurrentDataView();
@@ -380,10 +353,12 @@ export const useDiscoverHistogram = ({
[dispatch, setOverriddenVisContextAfterInvalidation, stateContainer.savedSearchState]
);
+ const chartHidden = useAppStateSelector((state) => state.hideChart);
+ const timeInterval = useAppStateSelector((state) => state.interval);
const breakdownField = useAppStateSelector((state) => state.breakdownField);
const onBreakdownFieldChange = useCallback<
- NonNullable
+ NonNullable
>(
(nextBreakdownField) => {
if (nextBreakdownField !== breakdownField) {
@@ -394,9 +369,17 @@ export const useDiscoverHistogram = ({
);
return {
- ref,
- getCreationOptions,
+ setUnifiedHistogramApi,
services,
+ localStorageKeyPrefix: 'discover',
+ requestAdapter: inspectorAdapters.requests,
+ abortController: getAbortController(),
+ initialState: {
+ chartHidden,
+ timeInterval,
+ totalHitsStatus: UnifiedHistogramFetchStatus.loading,
+ totalHitsResult: undefined,
+ },
dataView: isEsqlMode ? esqlDataView : dataView,
query: isEsqlMode ? esqlQuery : query,
filters: filtersMemoized,
diff --git a/src/platform/plugins/shared/discover/public/application/main/components/layout/discover_histogram_layout.test.tsx b/src/platform/plugins/shared/discover/public/application/main/components/layout/discover_histogram_layout.test.tsx
index eb9de0e297d7..e7746f2f6868 100644
--- a/src/platform/plugins/shared/discover/public/application/main/components/layout/discover_histogram_layout.test.tsx
+++ b/src/platform/plugins/shared/discover/public/application/main/components/layout/discover_histogram_layout.test.tsx
@@ -36,10 +36,17 @@ import { act } from 'react-dom/test-utils';
import { PanelsToggle } from '../../../../components/panels_toggle';
import { createDataViewDataSource } from '../../../../../common/data_sources';
import {
- CurrentTabProvider,
+ InternalStateProvider,
RuntimeStateProvider,
internalStateActions,
} from '../../state_management/redux';
+import { ChartPortalsRenderer } from '../chart';
+import { UnifiedHistogramChart } from '@kbn/unified-histogram';
+
+jest.mock('@elastic/eui', () => ({
+ ...jest.requireActual('@elastic/eui'),
+ useResizeObserver: jest.fn(() => ({ width: 1000, height: 1000 })),
+}));
function getStateContainer({
savedSearch,
@@ -155,13 +162,15 @@ const mountComponent = async ({
const component = mountWithIntl(
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
);
@@ -177,19 +186,19 @@ const mountComponent = async ({
describe('Discover histogram layout component', () => {
describe('render', () => {
- it('should render null if there is no search session', async () => {
+ it('should not render chart if there is no search session', async () => {
const { component } = await mountComponent({ searchSessionId: null });
- expect(component.isEmptyRender()).toBe(true);
+ expect(component.exists(UnifiedHistogramChart)).toBe(false);
});
- it('should not render null if there is a search session', async () => {
+ it('should render chart if there is a search session', async () => {
const { component } = await mountComponent();
- expect(component.isEmptyRender()).toBe(false);
+ expect(component.exists(UnifiedHistogramChart)).toBe(true);
}, 10000);
- it('should not render null if there is no search session, but isEsqlMode is true', async () => {
+ it('should render chart if there is no search session, but isEsqlMode is true', async () => {
const { component } = await mountComponent({ isEsqlMode: true });
- expect(component.isEmptyRender()).toBe(false);
+ expect(component.exists(UnifiedHistogramChart)).toBe(true);
});
it('should render PanelsToggle', async () => {
diff --git a/src/platform/plugins/shared/discover/public/application/main/components/layout/discover_histogram_layout.tsx b/src/platform/plugins/shared/discover/public/application/main/components/layout/discover_histogram_layout.tsx
index 2e1ece492170..38c897fd07bd 100644
--- a/src/platform/plugins/shared/discover/public/application/main/components/layout/discover_histogram_layout.tsx
+++ b/src/platform/plugins/shared/discover/public/application/main/components/layout/discover_histogram_layout.tsx
@@ -7,67 +7,40 @@
* License v3.0 only", or the "Server Side Public License, v 1".
*/
-import React, { useCallback } from 'react';
-import { UnifiedHistogramContainer } from '@kbn/unified-histogram-plugin/public';
-import { css } from '@emotion/react';
-import { useDiscoverHistogram } from './use_discover_histogram';
+import React from 'react';
+import { UnifiedHistogramLayout } from '@kbn/unified-histogram';
+import { OutPortal } from 'react-reverse-portal';
import { type DiscoverMainContentProps, DiscoverMainContent } from './discover_main_content';
-import { useAppStateSelector } from '../../state_management/discover_app_state_container';
-import { useIsEsqlMode } from '../../hooks/use_is_esql_mode';
+import { useCurrentChartPortalNode, useCurrentTabRuntimeState } from '../../state_management/redux';
export interface DiscoverHistogramLayoutProps extends DiscoverMainContentProps {
container: HTMLElement | null;
}
-const histogramLayoutCss = css`
- height: 100%;
-`;
-
export const DiscoverHistogramLayout = ({
- dataView,
- stateContainer,
container,
panelsToggle,
...mainContentProps
}: DiscoverHistogramLayoutProps) => {
- const { dataState } = stateContainer;
- const hideChart = useAppStateSelector((state) => state.hideChart);
- const isEsqlMode = useIsEsqlMode();
- const unifiedHistogramProps = useDiscoverHistogram({
- stateContainer,
- inspectorAdapters: dataState.inspectorAdapters,
- hideChart,
- });
-
- const renderCustomChartToggleActions = useCallback(
- () =>
- React.isValidElement(panelsToggle)
- ? React.cloneElement(panelsToggle, { renderedFor: 'histogram' })
- : panelsToggle,
- [panelsToggle]
+ const chartPortalNode = useCurrentChartPortalNode();
+ const layoutProps = useCurrentTabRuntimeState(
+ mainContentProps.stateContainer.runtimeStateManager,
+ (tab) => tab.unifiedHistogramLayoutProps$
);
- // Initialized when the first search has been requested or
- // when in ES|QL mode since search sessions are not supported
- if (!unifiedHistogramProps.searchSessionId && !isEsqlMode) {
+ if (!layoutProps) {
return null;
}
return (
- : null
+ }
+ {...layoutProps}
>
-
-
+
+
);
};
diff --git a/src/platform/plugins/shared/discover/public/application/main/components/layout/discover_layout.test.tsx b/src/platform/plugins/shared/discover/public/application/main/components/layout/discover_layout.test.tsx
index c2fcd7ed0ecc..4bae1f67bd3f 100644
--- a/src/platform/plugins/shared/discover/public/application/main/components/layout/discover_layout.test.tsx
+++ b/src/platform/plugins/shared/discover/public/application/main/components/layout/discover_layout.test.tsx
@@ -40,10 +40,11 @@ import { ErrorCallout } from '../../../../components/common/error_callout';
import { PanelsToggle } from '../../../../components/panels_toggle';
import { createDataViewDataSource } from '../../../../../common/data_sources';
import {
- CurrentTabProvider,
+ InternalStateProvider,
RuntimeStateProvider,
internalStateActions,
} from '../../state_management/redux';
+import { ChartPortalsRenderer } from '../chart';
jest.mock('@elastic/eui', () => ({
...jest.requireActual('@elastic/eui'),
@@ -137,15 +138,17 @@ async function mountComponent(
const component = mountWithIntl(
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
,
mountOptions
);
diff --git a/src/platform/plugins/shared/discover/public/application/main/components/layout/discover_layout.tsx b/src/platform/plugins/shared/discover/public/application/main/components/layout/discover_layout.tsx
index c3a06726d176..6f36a3d32e50 100644
--- a/src/platform/plugins/shared/discover/public/application/main/components/layout/discover_layout.tsx
+++ b/src/platform/plugins/shared/discover/public/application/main/components/layout/discover_layout.tsx
@@ -49,7 +49,6 @@ import type { SidebarToggleState } from '../../../types';
import { FetchStatus } from '../../../types';
import { useDataState } from '../../hooks/use_data_state';
import { SavedSearchURLConflictCallout } from '../../../../components/saved_search_url_conflict_callout/saved_search_url_conflict_callout';
-import { DiscoverHistogramLayout } from './discover_histogram_layout';
import { ErrorCallout } from '../../../../components/common/error_callout';
import { addLog } from '../../../../utils/add_log';
import { DiscoverResizableLayout } from './discover_resizable_layout';
@@ -59,6 +58,7 @@ import { sendErrorMsg } from '../../hooks/use_saved_search_messages';
import { useIsEsqlMode } from '../../hooks/use_is_esql_mode';
import { useCurrentDataView, useCurrentTabSelector } from '../../state_management/redux';
import { TABS_ENABLED } from '../../../../constants';
+import { DiscoverHistogramLayout } from './discover_histogram_layout';
const SidebarMemoized = React.memo(DiscoverSidebarResponsive);
const TopNavMemoized = React.memo(DiscoverTopNav);
diff --git a/src/platform/plugins/shared/discover/public/application/main/components/tabs_view/tabs_view.tsx b/src/platform/plugins/shared/discover/public/application/main/components/tabs_view/tabs_view.tsx
index c8902b2e3ed4..bb595e3ff780 100644
--- a/src/platform/plugins/shared/discover/public/application/main/components/tabs_view/tabs_view.tsx
+++ b/src/platform/plugins/shared/discover/public/application/main/components/tabs_view/tabs_view.tsx
@@ -12,7 +12,6 @@ import React, { useState } from 'react';
import { pick } from 'lodash';
import { DiscoverSessionView, type DiscoverSessionViewProps } from '../session_view';
import {
- CurrentTabProvider,
createTabItem,
internalStateActions,
selectAllTabs,
@@ -34,17 +33,10 @@ export const TabsView = (props: DiscoverSessionViewProps) => {
{
- const updateTabsAction = internalStateActions.updateTabs(updateState);
- return dispatch(updateTabsAction);
- }}
+ onChanged={(updateState) => dispatch(internalStateActions.updateTabs(updateState))}
createItem={() => createTabItem(allTabs)}
getPreviewData={getPreviewData}
- renderContent={() => (
-
-
-
- )}
+ renderContent={() => }
/>
);
};
diff --git a/src/platform/plugins/shared/discover/public/application/main/discover_main_route.tsx b/src/platform/plugins/shared/discover/public/application/main/discover_main_route.tsx
index 9d972d3cb536..42208f15c28e 100644
--- a/src/platform/plugins/shared/discover/public/application/main/discover_main_route.tsx
+++ b/src/platform/plugins/shared/discover/public/application/main/discover_main_route.tsx
@@ -21,7 +21,6 @@ import {
createInternalStateStore,
createRuntimeStateManager,
internalStateActions,
- CurrentTabProvider,
} from './state_management/redux';
import type { RootProfileState } from '../../context_awareness';
import { useRootProfile, useDefaultAdHocDataViews } from '../../context_awareness';
@@ -35,6 +34,7 @@ import {
import { useAsyncFunction } from './hooks/use_async_function';
import { TabsView } from './components/tabs_view';
import { TABS_ENABLED } from '../../constants';
+import { ChartPortalsRenderer } from './components/chart';
export interface MainRouteProps {
customizationContext: DiscoverCustomizationContext;
@@ -142,13 +142,13 @@ export const DiscoverMainRoute = ({
return (
- {TABS_ENABLED ? (
-
- ) : (
-
+
+ {TABS_ENABLED ? (
+
+ ) : (
-
- )}
+ )}
+
);
diff --git a/src/platform/plugins/shared/discover/public/application/main/state_management/discover_saved_search_container.ts b/src/platform/plugins/shared/discover/public/application/main/state_management/discover_saved_search_container.ts
index b379990e3044..1a590cec5b68 100644
--- a/src/platform/plugins/shared/discover/public/application/main/state_management/discover_saved_search_container.ts
+++ b/src/platform/plugins/shared/discover/public/application/main/state_management/discover_saved_search_container.ts
@@ -15,8 +15,8 @@ import type { FilterCompareOptions } from '@kbn/es-query';
import { COMPARE_ALL_OPTIONS, isOfAggregateQueryType, updateFilterReferences } from '@kbn/es-query';
import type { SearchSourceFields } from '@kbn/data-plugin/common';
import type { DataView, DataViewSpec } from '@kbn/data-views-plugin/common';
-import type { UnifiedHistogramVisContext } from '@kbn/unified-histogram-plugin/public';
-import { canImportVisContext } from '@kbn/unified-histogram-plugin/public';
+import type { UnifiedHistogramVisContext } from '@kbn/unified-histogram';
+import { canImportVisContext } from '@kbn/unified-histogram';
import type { SavedObjectSaveOpts } from '@kbn/saved-objects-plugin/public';
import { isEqual, isFunction } from 'lodash';
import { i18n } from '@kbn/i18n';
diff --git a/src/platform/plugins/shared/discover/public/application/main/state_management/redux/actions/initialize_session.ts b/src/platform/plugins/shared/discover/public/application/main/state_management/redux/actions/initialize_session.ts
index 277b5cdd1c1f..9dc8dff5fc13 100644
--- a/src/platform/plugins/shared/discover/public/application/main/state_management/redux/actions/initialize_session.ts
+++ b/src/platform/plugins/shared/discover/public/application/main/state_management/redux/actions/initialize_session.ts
@@ -68,12 +68,31 @@ export const initializeSession: InternalStateThunkActionCreator<
dispatch(disconnectTab({ tabId }));
dispatch(internalStateSlice.actions.resetOnSavedSearchChange({ tabId }));
+ const discoverSessionLoadTracker =
+ services.ebtManager.trackPerformanceEvent('discoverLoadSavedSearch');
+ const { currentDataView$, stateContainer$, customizationService$ } = selectTabRuntimeState(
+ runtimeStateManager,
+ tabId
+ );
+
+ /**
+ * New tab initialization or existing tab re-initialization
+ */
+
+ const wasTabInitialized = Boolean(stateContainer$.getValue());
+
+ if (wasTabInitialized) {
+ // Clear existing runtime state on re-initialization
+ // to ensure no stale state is used during loading
+ currentDataView$.next(undefined);
+ stateContainer$.next(undefined);
+ customizationService$.next(undefined);
+ }
+
/**
* "No data" checks
*/
- const discoverSessionLoadTracker =
- services.ebtManager.trackPerformanceEvent('discoverLoadSavedSearch');
const urlState = cleanupUrlState(
defaultUrlState ?? urlStateStorage.get(APP_STATE_URL_KEY),
services.uiSettings
@@ -124,10 +143,6 @@ export const initializeSession: InternalStateThunkActionCreator<
setBreadcrumbs({ services, titleBreadcrumbText: persistedDiscoverSession.title });
}
- const { currentDataView$, stateContainer$, customizationService$ } = selectTabRuntimeState(
- runtimeStateManager,
- tabId
- );
let dataView: DataView;
if (isOfAggregateQueryType(initialQuery)) {
diff --git a/src/platform/plugins/shared/discover/public/application/main/state_management/redux/hooks.tsx b/src/platform/plugins/shared/discover/public/application/main/state_management/redux/hooks.tsx
index 48aae430182a..645e8f6729be 100644
--- a/src/platform/plugins/shared/discover/public/application/main/state_management/redux/hooks.tsx
+++ b/src/platform/plugins/shared/discover/public/application/main/state_management/redux/hooks.tsx
@@ -15,7 +15,8 @@ import {
createDispatchHook,
createSelectorHook,
} from 'react-redux';
-import React, { type PropsWithChildren, useMemo, createContext } from 'react';
+import type { PropsWithChildren } from 'react';
+import React, { useMemo, createContext } from 'react';
import { useAdHocDataViews } from './runtime_state';
import type { DiscoverInternalState, TabState } from './types';
import {
@@ -25,6 +26,7 @@ import {
} from './internal_state';
import { selectTab } from './selectors';
import { type TabActionInjector, createTabActionInjector } from './utils';
+import type { ChartPortalNode } from '../../components/chart';
const internalStateContext = createContext(
// Recommended approach for versions of Redux prior to v9:
@@ -49,6 +51,7 @@ export const useInternalStateSelector: TypedUseSelectorHook(unde
export const CurrentTabProvider = ({
currentTabId,
+ currentChartPortalNode,
children,
-}: PropsWithChildren<{ currentTabId: string }>) => {
+}: PropsWithChildren<{ currentTabId: string; currentChartPortalNode?: ChartPortalNode }>) => {
const contextValue = useMemo(
- () => ({ currentTabId, injectCurrentTab: createTabActionInjector(currentTabId) }),
- [currentTabId]
+ () => ({
+ currentTabId,
+ currentChartPortalNode,
+ injectCurrentTab: createTabActionInjector(currentTabId),
+ }),
+ [currentChartPortalNode, currentTabId]
);
return {children};
@@ -88,6 +96,8 @@ export const useCurrentTabAction = (
return useMemo(() => injectCurrentTab(actionCreator), [actionCreator, injectCurrentTab]);
};
+export const useCurrentChartPortalNode = () => useCurrentTabContext().currentChartPortalNode;
+
export const useDataViewsForPicker = () => {
const originalAdHocDataViews = useAdHocDataViews();
const savedDataViews = useInternalStateSelector((state) => state.savedDataViews);
diff --git a/src/platform/plugins/shared/discover/public/application/main/state_management/redux/index.ts b/src/platform/plugins/shared/discover/public/application/main/state_management/redux/index.ts
index 4116b8eb3d5f..fc821aa4c764 100644
--- a/src/platform/plugins/shared/discover/public/application/main/state_management/redux/index.ts
+++ b/src/platform/plugins/shared/discover/public/application/main/state_management/redux/index.ts
@@ -52,6 +52,7 @@ export {
CurrentTabProvider,
useCurrentTabSelector,
useCurrentTabAction,
+ useCurrentChartPortalNode,
useDataViewsForPicker,
} from './hooks';
diff --git a/src/platform/plugins/shared/discover/public/application/main/state_management/redux/internal_state.ts b/src/platform/plugins/shared/discover/public/application/main/state_management/redux/internal_state.ts
index 6007abdf1181..e95846920f78 100644
--- a/src/platform/plugins/shared/discover/public/application/main/state_management/redux/internal_state.ts
+++ b/src/platform/plugins/shared/discover/public/application/main/state_management/redux/internal_state.ts
@@ -193,11 +193,16 @@ export interface InternalStateThunkDependencies {
urlStateStorage: IKbnUrlStateStorage;
}
+const IS_JEST_ENVIRONMENT = typeof jest !== 'undefined';
+
export const createInternalStateStore = (options: InternalStateThunkDependencies) => {
const store = configureStore({
reducer: internalStateSlice.reducer,
middleware: (getDefaultMiddleware) =>
- getDefaultMiddleware({ thunk: { extraArgument: options } }),
+ getDefaultMiddleware({
+ thunk: { extraArgument: options },
+ serializableCheck: !IS_JEST_ENVIRONMENT,
+ }),
});
// TEMPORARY: Create initial default tab
diff --git a/src/platform/plugins/shared/discover/public/application/main/state_management/redux/runtime_state.tsx b/src/platform/plugins/shared/discover/public/application/main/state_management/redux/runtime_state.tsx
index ae4bd3c61dfc..ed2cfa050f7d 100644
--- a/src/platform/plugins/shared/discover/public/application/main/state_management/redux/runtime_state.tsx
+++ b/src/platform/plugins/shared/discover/public/application/main/state_management/redux/runtime_state.tsx
@@ -11,6 +11,7 @@ import type { DataView } from '@kbn/data-views-plugin/common';
import React, { type PropsWithChildren, createContext, useContext, useMemo } from 'react';
import useObservable from 'react-use/lib/useObservable';
import { BehaviorSubject } from 'rxjs';
+import type { UnifiedHistogramPartialLayoutProps } from '@kbn/unified-histogram';
import { useCurrentTabContext } from './hooks';
import type { DiscoverStateContainer } from '../discover_state';
import type { ConnectedCustomizationService } from '../../../../customizations';
@@ -22,6 +23,7 @@ interface DiscoverRuntimeState {
interface TabRuntimeState {
stateContainer?: DiscoverStateContainer;
customizationService?: ConnectedCustomizationService;
+ unifiedHistogramLayoutProps?: UnifiedHistogramPartialLayoutProps;
currentDataView: DataView;
}
@@ -45,6 +47,9 @@ export const createRuntimeStateManager = (): RuntimeStateManager => ({
export const createTabRuntimeState = (): ReactiveTabRuntimeState => ({
stateContainer$: new BehaviorSubject(undefined),
customizationService$: new BehaviorSubject(undefined),
+ unifiedHistogramLayoutProps$: new BehaviorSubject(
+ undefined
+ ),
currentDataView$: new BehaviorSubject(undefined),
});
diff --git a/src/platform/plugins/shared/discover/public/application/main/state_management/redux/selectors.ts b/src/platform/plugins/shared/discover/public/application/main/state_management/redux/selectors.ts
index bdeac56eaa27..382318a9d025 100644
--- a/src/platform/plugins/shared/discover/public/application/main/state_management/redux/selectors.ts
+++ b/src/platform/plugins/shared/discover/public/application/main/state_management/redux/selectors.ts
@@ -7,9 +7,15 @@
* License v3.0 only", or the "Server Side Public License, v 1".
*/
+import { createSelector } from '@reduxjs/toolkit';
import type { DiscoverInternalState } from './types';
export const selectTab = (state: DiscoverInternalState, tabId: string) => state.tabs.byId[tabId];
-export const selectAllTabs = (state: DiscoverInternalState) =>
- state.tabs.allIds.map((id) => selectTab(state, id));
+export const selectAllTabs = createSelector(
+ [
+ (state: DiscoverInternalState) => state.tabs.allIds,
+ (state: DiscoverInternalState) => state.tabs.byId,
+ ],
+ (allIds, byId) => allIds.map((id) => byId[id])
+);
diff --git a/src/platform/plugins/shared/discover/public/application/main/state_management/redux/types.ts b/src/platform/plugins/shared/discover/public/application/main/state_management/redux/types.ts
index 7799ee913300..4e5afab25577 100644
--- a/src/platform/plugins/shared/discover/public/application/main/state_management/redux/types.ts
+++ b/src/platform/plugins/shared/discover/public/application/main/state_management/redux/types.ts
@@ -11,7 +11,7 @@ import type { RefreshInterval } from '@kbn/data-plugin/common';
import type { DataViewListItem } from '@kbn/data-views-plugin/public';
import type { DataTableRecord } from '@kbn/discover-utils';
import type { Filter, TimeRange } from '@kbn/es-query';
-import type { UnifiedHistogramVisContext } from '@kbn/unified-histogram-plugin/public';
+import type { UnifiedHistogramVisContext } from '@kbn/unified-histogram';
import type { TabItem } from '@kbn/unified-tabs';
export enum LoadingStatus {
diff --git a/src/platform/plugins/shared/discover/public/application/main/state_management/utils/get_state_defaults.ts b/src/platform/plugins/shared/discover/public/application/main/state_management/utils/get_state_defaults.ts
index f448128f2f63..9932d2363f07 100644
--- a/src/platform/plugins/shared/discover/public/application/main/state_management/utils/get_state_defaults.ts
+++ b/src/platform/plugins/shared/discover/public/application/main/state_management/utils/get_state_defaults.ts
@@ -10,7 +10,7 @@
import { cloneDeep } from 'lodash';
import type { IUiSettingsClient } from '@kbn/core/public';
import type { SavedSearch } from '@kbn/saved-search-plugin/public';
-import { getChartHidden } from '@kbn/unified-histogram-plugin/public';
+import { getChartHidden } from '@kbn/unified-histogram';
import {
DEFAULT_COLUMNS_SETTING,
DOC_HIDE_TIME_COLUMN_SETTING,
diff --git a/src/platform/plugins/shared/discover/public/customizations/customization_types/histogram_customization.tsx b/src/platform/plugins/shared/discover/public/customizations/customization_types/histogram_customization.tsx
index 6cb6a23f95e6..41ff96950d44 100644
--- a/src/platform/plugins/shared/discover/public/customizations/customization_types/histogram_customization.tsx
+++ b/src/platform/plugins/shared/discover/public/customizations/customization_types/histogram_customization.tsx
@@ -7,7 +7,7 @@
* License v3.0 only", or the "Server Side Public License, v 1".
*/
-import type { UnifiedHistogramContainerProps } from '@kbn/unified-histogram-plugin/public';
+import type { UseUnifiedHistogramProps } from '@kbn/unified-histogram';
interface UnifiedHistogramCustomizationId {
id: 'unified_histogram';
@@ -15,6 +15,6 @@ interface UnifiedHistogramCustomizationId {
export type UnifiedHistogramCustomization = UnifiedHistogramCustomizationId &
Pick<
- UnifiedHistogramContainerProps,
+ UseUnifiedHistogramProps,
'onFilter' | 'onBrushEnd' | 'withDefaultActions' | 'disabledActions'
>;
diff --git a/src/platform/plugins/shared/discover/tsconfig.json b/src/platform/plugins/shared/discover/tsconfig.json
index 0ab3958edfaa..88c3deed3a3b 100644
--- a/src/platform/plugins/shared/discover/tsconfig.json
+++ b/src/platform/plugins/shared/discover/tsconfig.json
@@ -36,7 +36,6 @@
"@kbn/data-view-editor-plugin",
"@kbn/triggers-actions-ui-plugin",
"@kbn/saved-objects-tagging-oss-plugin",
- "@kbn/unified-histogram-plugin",
"@kbn/analytics",
"@kbn/saved-objects-management-plugin",
"@kbn/lens-plugin",
@@ -104,7 +103,8 @@
"@kbn/embeddable-enhanced-plugin",
"@kbn/shared-ux-page-analytics-no-data-types",
"@kbn/core-application-browser-mocks",
- "@kbn/unified-tabs"
+ "@kbn/unified-tabs",
+ "@kbn/unified-histogram"
],
"exclude": ["target/**/*"]
}
diff --git a/src/platform/plugins/shared/unified_histogram/README.md b/src/platform/plugins/shared/unified_histogram/README.md
deleted file mode 100755
index 177cd6524d0f..000000000000
--- a/src/platform/plugins/shared/unified_histogram/README.md
+++ /dev/null
@@ -1,147 +0,0 @@
-# unifiedHistogram
-
-Unified Histogram is a UX Building Block including a layout with a resizable histogram and a main display.
-It manages its own state and data fetching, and can easily be dropped into pages with minimal setup.
-
-## Basic Usage
-
-```tsx
-// Import the container component
-import { UnifiedHistogramContainer } from '@kbn/unified-histogram-plugin/public';
-
-// Import modules required for your application
-import { useServices, useResizeRef, useRequestParams, MyLayout, MyButton } from './my-modules';
-
-const services = useServices();
-const resizeRef = useResizeRef();
-const { dataView, query, filters, timeRange, relativeTimeRange, searchSessionId, requestAdapter } =
- useRequestParams();
-
-return (
-
-
-
-);
-```
-
-## Advanced Usage
-
-```tsx
-// Import the container component and API contract
-import {
- UnifiedHistogramContainer,
- type UnifiedHistogramApi,
-} from '@kbn/unified-histogram-plugin/public';
-
-// Import modules required for your application
-import {
- useServices,
- useResizeRef,
- useCallbacks,
- useRequestParams,
- useStateParams,
- useFetch,
- MyLayout,
- MyButton,
-} from './my-modules';
-
-const services = useServices();
-const resizeRef = useResizeRef();
-const { onChartHiddenChange, onLensRequestAdapterChange } = useCallbacks();
-const { chartHidden, breakdownField } = useStateParams();
-const {
- dataView,
- query,
- filters,
- timeRange,
- relativeTimeRange,
- searchSessionId,
- requestAdapter,
-} = useRequestParams();
-
-// Use a state variable instead of a ref to preserve reactivity when the API is updated
-const [unifiedHistogram, setUnifiedHistogram] = useState();
-
-const getCreationOptions = useCallback(() => ({
- // Optionally provide a local storage key prefix to save parts of the state,
- // such as the chart hidden state and top panel height, to local storage
- localStorageKeyPrefix: 'myApp',
- // Customize the initial state in order to override the defaults
- initialState: { chartHidden, breakdownField },
-}), [...]);
-
-// Trigger a fetch, must be called on init to render the chart
-useFetch(() => {
- unifiedHistogram?.fetch();
-});
-
-// Update the Unified Histogram state when our state params change
-useEffect(() => {
- unifiedHistogram?.setChartHidden(chartHidden);
-}, [chartHidden]);
-
-useEffect(() => {
- unifiedHistogram?.setBreakdownField(breakdownField);
-}, [breakdownField]);
-
-// Listen for state changes if your application requires it
-useEffect(() => {
- const subscription = unifiedHistogram?.state$
- .pipe(map((state) => state.chartHidden), distinctUntilChanged())
- .subscribe(onChartHiddenChange);
-
- return () => {
- subscription?.unsubscribe();
- };
-}, [...]);
-
-// Currently Lens does not accept a custom request adapter,
-// so it will not use the one passed to Unified Histogram.
-// Instead you can get access to the one it's using by
-// listening for state changes
-useEffect(() => {
- const subscription = unifiedHistogram?.state$
- .pipe(map((state) => state.lensRequestAdapter), distinctUntilChanged())
- .subscribe(onLensRequestAdapterChange);
-
- return () => {
- subscription?.unsubscribe();
- };
-}, [...]);
-
-return (
-
-
-
-);
-```
diff --git a/src/platform/plugins/shared/unified_histogram/kibana.jsonc b/src/platform/plugins/shared/unified_histogram/kibana.jsonc
deleted file mode 100644
index 7001d67cad7c..000000000000
--- a/src/platform/plugins/shared/unified_histogram/kibana.jsonc
+++ /dev/null
@@ -1,21 +0,0 @@
-{
- "type": "plugin",
- "id": "@kbn/unified-histogram-plugin",
- "owner": [
- "@elastic/kibana-data-discovery"
- ],
- "group": "platform",
- "visibility": "shared",
- "description": "The `unifiedHistogram` plugin provides UI components to create a layout including a resizable histogram and a main display.",
- "plugin": {
- "id": "unifiedHistogram",
- "browser": true,
- "server": false,
- "requiredBundles": [
- "data",
- "dataViews",
- "inspector",
- "visualizations"
- ]
- }
-}
\ No newline at end of file
diff --git a/src/platform/plugins/shared/unified_histogram/public/container/container.test.tsx b/src/platform/plugins/shared/unified_histogram/public/container/container.test.tsx
deleted file mode 100644
index d67d4fc4fd81..000000000000
--- a/src/platform/plugins/shared/unified_histogram/public/container/container.test.tsx
+++ /dev/null
@@ -1,78 +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", the "GNU Affero General Public License v3.0 only", and the "Server Side
- * Public License v 1"; you may not use this file except in compliance with, at
- * your election, the "Elastic License 2.0", the "GNU Affero General Public
- * License v3.0 only", or the "Server Side Public License, v 1".
- */
-
-import { RequestAdapter } from '@kbn/inspector-plugin/common';
-import { mountWithIntl } from '@kbn/test-jest-helpers';
-import React from 'react';
-import { act } from 'react-dom/test-utils';
-import { UnifiedHistogramLayout } from '../layout';
-import { dataViewWithTimefieldMock } from '../__mocks__/data_view_with_timefield';
-import { unifiedHistogramServicesMock } from '../__mocks__/services';
-import { UnifiedHistogramApi, UnifiedHistogramContainer } from './container';
-
-describe('UnifiedHistogramContainer', () => {
- it('should initialize', async () => {
- let api: UnifiedHistogramApi | undefined;
- const setApi = (ref: UnifiedHistogramApi) => {
- api = ref;
- };
- const getCreationOptions = jest.fn(() => ({ initialState: { timeInterval: '42s' } }));
- const component = mountWithIntl(
-
- );
- expect(component.update().isEmptyRender()).toBe(true);
- await act(() => new Promise((resolve) => setTimeout(resolve, 0)));
- component.update();
- expect(getCreationOptions).toHaveBeenCalled();
- expect(component.find(UnifiedHistogramLayout).prop('chart')?.timeInterval).toBe('42s');
- expect(component.update().isEmptyRender()).toBe(false);
- expect(api).toBeDefined();
- });
-
- it('should trigger input$ when fetch is called', async () => {
- let api: UnifiedHistogramApi | undefined;
- const setApi = (ref: UnifiedHistogramApi) => {
- api = ref;
- };
- const component = mountWithIntl(
-
- );
- await act(() => new Promise((resolve) => setTimeout(resolve, 0)));
- component.update();
- const input$ = component.find(UnifiedHistogramLayout).prop('input$');
- const inputSpy = jest.fn();
- input$?.subscribe(inputSpy);
- act(() => {
- api?.fetch();
- });
- expect(inputSpy).toHaveBeenCalledTimes(1);
- expect(inputSpy).toHaveBeenCalledWith({ type: 'fetch' });
- });
-});
diff --git a/src/platform/plugins/shared/unified_histogram/public/container/container.tsx b/src/platform/plugins/shared/unified_histogram/public/container/container.tsx
deleted file mode 100644
index 5d83f8e84101..000000000000
--- a/src/platform/plugins/shared/unified_histogram/public/container/container.tsx
+++ /dev/null
@@ -1,196 +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", the "GNU Affero General Public License v3.0 only", and the "Server Side
- * Public License v 1"; you may not use this file except in compliance with, at
- * your election, the "Elastic License 2.0", the "GNU Affero General Public
- * License v3.0 only", or the "Server Side Public License, v 1".
- */
-
-import React, { forwardRef, useEffect, useImperativeHandle, useMemo, useState } from 'react';
-import { Subject } from 'rxjs';
-import { pick } from 'lodash';
-import useMount from 'react-use/lib/useMount';
-import { LensSuggestionsApi } from '@kbn/lens-plugin/public';
-import { UnifiedHistogramLayout, UnifiedHistogramLayoutProps } from '../layout';
-import {
- UnifiedHistogramExternalVisContextStatus,
- UnifiedHistogramInputMessage,
- UnifiedHistogramRequestContext,
- UnifiedHistogramVisContext,
-} from '../types';
-import {
- createStateService,
- UnifiedHistogramStateOptions,
- UnifiedHistogramStateService,
-} from './services/state_service';
-import { useStateProps } from './hooks/use_state_props';
-import { useStateSelector } from './utils/use_state_selector';
-import { topPanelHeightSelector } from './utils/state_selectors';
-import { exportVisContext } from '../utils/external_vis_context';
-import { getBreakdownField } from './utils/local_storage_utils';
-
-type LayoutProps = Pick;
-
-/**
- * The options used to initialize the container
- */
-export type UnifiedHistogramCreationOptions = Omit &
- LayoutProps;
-
-/**
- * The props exposed by the container
- */
-export type UnifiedHistogramContainerProps = {
- getCreationOptions?: () =>
- | UnifiedHistogramCreationOptions
- | Promise;
- searchSessionId?: UnifiedHistogramRequestContext['searchSessionId'];
- requestAdapter?: UnifiedHistogramRequestContext['adapter'];
- isChartLoading?: boolean;
- breakdownField?: string;
- onBreakdownFieldChange?: (breakdownField: string | undefined) => void;
- onVisContextChanged?: (
- nextVisContext: UnifiedHistogramVisContext | undefined,
- externalVisContextStatus: UnifiedHistogramExternalVisContextStatus
- ) => void;
-} & Pick<
- UnifiedHistogramLayoutProps,
- | 'services'
- | 'className'
- | 'dataView'
- | 'query'
- | 'filters'
- | 'timeRange'
- | 'relativeTimeRange'
- | 'columns'
- | 'table'
- | 'container'
- | 'renderCustomChartToggleActions'
- | 'children'
- | 'onBrushEnd'
- | 'onFilter'
- | 'externalVisContext'
- | 'withDefaultActions'
- | 'disabledActions'
- | 'abortController'
->;
-
-/**
- * The API exposed by the container
- */
-export type UnifiedHistogramApi = {
- /**
- * Trigger a fetch of the data
- */
- fetch: () => void;
-} & Pick<
- UnifiedHistogramStateService,
- 'state$' | 'setChartHidden' | 'setTopPanelHeight' | 'setTimeInterval' | 'setTotalHits'
->;
-
-export const UnifiedHistogramContainer = forwardRef<
- UnifiedHistogramApi,
- UnifiedHistogramContainerProps
->(({ onBreakdownFieldChange, onVisContextChanged, ...containerProps }, ref) => {
- const [layoutProps, setLayoutProps] = useState();
- const [localStorageKeyPrefix, setLocalStorageKeyPrefix] = useState();
- const [stateService, setStateService] = useState();
- const [lensSuggestionsApi, setLensSuggestionsApi] = useState();
- const [input$] = useState(() => new Subject());
- const [api, setApi] = useState();
-
- // Expose the API to the parent component
- useImperativeHandle(ref, () => api!, [api]);
-
- // Call for creation options once the container is mounted
- useMount(async () => {
- const { getCreationOptions, services } = containerProps;
- const options = await getCreationOptions?.();
- const apiHelper = await services.lens.stateHelperApi();
-
- setLayoutProps(pick(options, 'disableTriggers', 'disabledActions'));
- setLocalStorageKeyPrefix(options?.localStorageKeyPrefix);
- setStateService(createStateService({ services, ...options }));
- setLensSuggestionsApi(() => apiHelper.suggestions);
- });
-
- // Initialize the API once the state service is available
- useEffect(() => {
- if (!stateService) {
- return;
- }
-
- setApi({
- fetch: () => {
- input$.next({ type: 'fetch' });
- },
- ...pick(
- stateService,
- 'state$',
- 'setChartHidden',
- 'setTopPanelHeight',
- 'setTimeInterval',
- 'setTotalHits'
- ),
- });
- }, [input$, stateService]);
-
- const { services, dataView, query, columns, searchSessionId, requestAdapter, isChartLoading } =
- containerProps;
- const topPanelHeight = useStateSelector(stateService?.state$, topPanelHeightSelector);
- const initialBreakdownField = useMemo(
- () =>
- localStorageKeyPrefix
- ? getBreakdownField(services.storage, localStorageKeyPrefix)
- : undefined,
- [localStorageKeyPrefix, services.storage]
- );
- const stateProps = useStateProps({
- services,
- localStorageKeyPrefix,
- stateService,
- dataView,
- query,
- searchSessionId,
- requestAdapter,
- columns,
- breakdownField: initialBreakdownField,
- ...pick(containerProps, 'breakdownField'),
- onBreakdownFieldChange,
- });
-
- const handleVisContextChange: UnifiedHistogramLayoutProps['onVisContextChanged'] | undefined =
- useMemo(() => {
- if (!onVisContextChanged) {
- return undefined;
- }
-
- return (visContext, externalVisContextStatus) => {
- const minifiedVisContext = exportVisContext(visContext);
-
- onVisContextChanged(minifiedVisContext, externalVisContextStatus);
- };
- }, [onVisContextChanged]);
-
- // Don't render anything until the container is initialized
- if (!layoutProps || !lensSuggestionsApi || !api) {
- return null;
- }
-
- return (
-
- );
-});
-
-// eslint-disable-next-line import/no-default-export
-export default UnifiedHistogramContainer;
diff --git a/src/platform/plugins/shared/unified_histogram/public/container/index.tsx b/src/platform/plugins/shared/unified_histogram/public/container/index.tsx
deleted file mode 100644
index 5b4fa6a8d190..000000000000
--- a/src/platform/plugins/shared/unified_histogram/public/container/index.tsx
+++ /dev/null
@@ -1,52 +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", the "GNU Affero General Public License v3.0 only", and the "Server Side
- * Public License v 1"; you may not use this file except in compliance with, at
- * your election, the "Elastic License 2.0", the "GNU Affero General Public
- * License v3.0 only", or the "Server Side Public License, v 1".
- */
-
-import { EuiDelayRender, EuiFlexGroup, EuiLoadingSpinner } from '@elastic/eui';
-import { withSuspense } from '@kbn/shared-ux-utility';
-import React, { lazy } from 'react';
-import type { UnifiedHistogramApi, UnifiedHistogramContainerProps } from './container';
-
-export type {
- UnifiedHistogramApi,
- UnifiedHistogramContainerProps,
- UnifiedHistogramCreationOptions,
-} from './container';
-export type { UnifiedHistogramState, UnifiedHistogramStateOptions } from './services/state_service';
-export {
- getChartHidden,
- getTopPanelHeight,
- getBreakdownField,
- setChartHidden,
- setTopPanelHeight,
- setBreakdownField,
-} from './utils/local_storage_utils';
-
-const LazyUnifiedHistogramContainer = lazy(() => import('./container'));
-
-/**
- * A resizable layout component with two panels that renders a histogram with a hits
- * counter in the top panel, and a main display (data table, etc.) in the bottom panel.
- */
-export const UnifiedHistogramContainer = withSuspense<
- UnifiedHistogramContainerProps,
- UnifiedHistogramApi
->(
- LazyUnifiedHistogramContainer,
-
-
-
-
-
-);
diff --git a/src/platform/plugins/shared/unified_histogram/public/layout/layout.tsx b/src/platform/plugins/shared/unified_histogram/public/layout/layout.tsx
deleted file mode 100644
index 5d497990e30f..000000000000
--- a/src/platform/plugins/shared/unified_histogram/public/layout/layout.tsx
+++ /dev/null
@@ -1,394 +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", the "GNU Affero General Public License v3.0 only", and the "Server Side
- * Public License v 1"; you may not use this file except in compliance with, at
- * your election, the "Elastic License 2.0", the "GNU Affero General Public
- * License v3.0 only", or the "Server Side Public License, v 1".
- */
-
-import { EuiSpacer, useEuiTheme, useIsWithinBreakpoints } from '@elastic/eui';
-import React, { PropsWithChildren, ReactElement, useEffect, useMemo, useState } from 'react';
-import useObservable from 'react-use/lib/useObservable';
-import { createHtmlPortalNode, InPortal, OutPortal } from 'react-reverse-portal';
-import { css } from '@emotion/css';
-import type { Datatable, DatatableColumn } from '@kbn/expressions-plugin/common';
-import type { DataView, DataViewField } from '@kbn/data-views-plugin/public';
-import type {
- EmbeddableComponentProps,
- LensEmbeddableInput,
- LensEmbeddableOutput,
- LensSuggestionsApi,
-} from '@kbn/lens-plugin/public';
-import { AggregateQuery, Filter, Query, TimeRange } from '@kbn/es-query';
-import {
- ResizableLayout,
- ResizableLayoutDirection,
- ResizableLayoutMode,
-} from '@kbn/resizable-layout';
-import { Chart, checkChartAvailability } from '../chart';
-import {
- UnifiedHistogramVisContext,
- UnifiedHistogramBreakdownContext,
- UnifiedHistogramChartContext,
- UnifiedHistogramChartLoadEvent,
- UnifiedHistogramFetchStatus,
- UnifiedHistogramHitsContext,
- UnifiedHistogramInput$,
- UnifiedHistogramRequestContext,
- UnifiedHistogramServices,
- UnifiedHistogramSuggestionContext,
- UnifiedHistogramExternalVisContextStatus,
-} from '../types';
-import { UnifiedHistogramSuggestionType } from '../types';
-import { LensVisService } from '../services/lens_vis_service';
-import { useRequestParams } from '../hooks/use_request_params';
-
-const ChartMemoized = React.memo(Chart);
-
-const chartSpacer = ;
-
-export interface UnifiedHistogramLayoutProps extends PropsWithChildren {
- /**
- * Optional class name to add to the layout container
- */
- className?: string;
- /**
- * Required services
- */
- services: UnifiedHistogramServices;
- /**
- * The current data view
- */
- dataView: DataView;
- /**
- * The current query
- */
- query?: Query | AggregateQuery;
- /**
- * The current filters
- */
- filters?: Filter[];
- /**
- * The external custom Lens vis
- */
- externalVisContext?: UnifiedHistogramVisContext;
- /**
- * Flag that indicates that a text based language is used
- */
- isPlainRecord?: boolean;
- /**
- * The current time range
- */
- timeRange?: TimeRange;
- /**
- * The relative time range, used when timeRange is an absolute range (e.g. for edit visualization button)
- */
- relativeTimeRange?: TimeRange;
- /**
- * The current columns
- */
- columns?: DatatableColumn[];
- /**
- * Context object for requests made by Unified Histogram components -- optional
- */
- request?: UnifiedHistogramRequestContext;
- /**
- * Context object for the hits count -- leave undefined to hide the hits count
- */
- hits?: UnifiedHistogramHitsContext;
- lensAdapters?: UnifiedHistogramChartLoadEvent['adapters'];
- dataLoading$?: LensEmbeddableOutput['dataLoading$'];
- /**
- * Context object for the chart -- leave undefined to hide the chart
- */
- chart?: UnifiedHistogramChartContext;
- /**
- * Context object for the breakdown -- leave undefined to hide the breakdown
- */
- breakdown?: UnifiedHistogramBreakdownContext;
- /**
- * The parent container element, used to calculate the layout size
- */
- container: HTMLElement | null;
- /**
- * Current top panel height -- leave undefined to use the default
- */
- topPanelHeight?: number;
- /**
- * This element would replace the default chart toggle buttons
- */
- renderCustomChartToggleActions?: () => ReactElement | undefined;
- /**
- * Disable triggers for the Lens embeddable
- */
- disableTriggers?: LensEmbeddableInput['disableTriggers'];
- /**
- * Disabled action IDs for the Lens embeddable
- */
- disabledActions?: LensEmbeddableInput['disabledActions'];
- /**
- * Input observable
- */
- input$?: UnifiedHistogramInput$;
- /**
- * Flag indicating that the chart is currently loading
- */
- isChartLoading: boolean;
- /**
- * The Lens suggestions API
- */
- lensSuggestionsApi: LensSuggestionsApi;
- /**
- * Callback to update the topPanelHeight prop when a resize is triggered
- */
- onTopPanelHeightChange?: (topPanelHeight: number | undefined) => void;
- /**
- * Callback to hide or show the chart -- should set {@link UnifiedHistogramChartContext.hidden} to chartHidden
- */
- onChartHiddenChange?: (chartHidden: boolean) => void;
- /**
- * Callback to update the time interval -- should set {@link UnifiedHistogramChartContext.timeInterval} to timeInterval
- */
- onTimeIntervalChange?: (timeInterval: string) => void;
- /**
- * Callback to update the breakdown field -- should set {@link UnifiedHistogramBreakdownContext.field} to breakdownField
- */
- onBreakdownFieldChange?: (breakdownField: DataViewField | undefined) => void;
- /**
- * Callback to update the suggested chart
- */
- onSuggestionContextChange: (
- suggestionContext: UnifiedHistogramSuggestionContext | undefined
- ) => void;
- /**
- * Callback to notify about the change in Lens attributes
- */
- onVisContextChanged?: (
- visContext: UnifiedHistogramVisContext | undefined,
- externalVisContextStatus: UnifiedHistogramExternalVisContextStatus
- ) => void;
- /**
- * Callback to update the total hits -- should set {@link UnifiedHistogramHitsContext.status} to status
- * and {@link UnifiedHistogramHitsContext.total} to result
- */
- onTotalHitsChange?: (status: UnifiedHistogramFetchStatus, result?: number | Error) => void;
- /**
- * Called when the histogram loading status changes
- */
- onChartLoad?: (event: UnifiedHistogramChartLoadEvent) => void;
- /**
- * Callback to pass to the Lens embeddable to handle filter changes
- */
- onFilter?: LensEmbeddableInput['onFilter'];
- /**
- * Callback to pass to the Lens embeddable to handle brush events
- */
- onBrushEnd?: LensEmbeddableInput['onBrushEnd'];
- /**
- * Allows users to enable/disable default actions
- */
- withDefaultActions?: EmbeddableComponentProps['withDefaultActions'];
-
- table?: Datatable;
- abortController?: AbortController;
-}
-
-export const UnifiedHistogramLayout = ({
- className,
- services,
- dataView,
- query: originalQuery,
- filters: originalFilters,
- externalVisContext,
- isChartLoading,
- isPlainRecord,
- timeRange: originalTimeRange,
- relativeTimeRange,
- columns,
- request,
- hits,
- lensAdapters,
- dataLoading$,
- chart: originalChart,
- breakdown,
- container,
- topPanelHeight,
- renderCustomChartToggleActions,
- disableTriggers,
- disabledActions,
- lensSuggestionsApi,
- input$,
- table,
- onTopPanelHeightChange,
- onChartHiddenChange,
- onTimeIntervalChange,
- onBreakdownFieldChange,
- onSuggestionContextChange,
- onVisContextChanged,
- onTotalHitsChange,
- onChartLoad,
- onFilter,
- onBrushEnd,
- children,
- withDefaultActions,
- abortController,
-}: UnifiedHistogramLayoutProps) => {
- const columnsMap = useMemo(() => {
- if (!columns?.length) {
- return undefined;
- }
-
- return columns.reduce((acc, column) => {
- acc[column.id] = column;
- return acc;
- }, {} as Record);
- }, [columns]);
-
- const requestParams = useRequestParams({
- services,
- query: originalQuery,
- filters: originalFilters,
- timeRange: originalTimeRange,
- });
-
- const [lensVisService] = useState(() => new LensVisService({ services, lensSuggestionsApi }));
- const lensVisServiceCurrentSuggestionContext = useObservable(
- lensVisService.currentSuggestionContext$
- );
-
- const originalChartTimeInterval = originalChart?.timeInterval;
- useEffect(() => {
- if (isChartLoading) {
- return;
- }
-
- lensVisService.update({
- externalVisContext,
- queryParams: {
- dataView,
- query: requestParams.query,
- filters: requestParams.filters,
- timeRange: originalTimeRange,
- isPlainRecord,
- columns,
- columnsMap,
- },
- timeInterval: originalChartTimeInterval,
- breakdownField: breakdown?.field,
- table,
- onSuggestionContextChange,
- onVisContextChanged: isPlainRecord ? onVisContextChanged : undefined,
- });
- }, [
- lensVisService,
- dataView,
- requestParams.query,
- requestParams.filters,
- originalTimeRange,
- originalChartTimeInterval,
- isPlainRecord,
- columns,
- columnsMap,
- breakdown,
- externalVisContext,
- onSuggestionContextChange,
- onVisContextChanged,
- isChartLoading,
- table,
- ]);
-
- const chart =
- !lensVisServiceCurrentSuggestionContext?.type ||
- lensVisServiceCurrentSuggestionContext.type === UnifiedHistogramSuggestionType.unsupported
- ? undefined
- : originalChart;
- const isChartAvailable = checkChartAvailability({ chart, dataView, isPlainRecord });
-
- const [topPanelNode] = useState(() =>
- createHtmlPortalNode({ attributes: { class: 'eui-fullHeight' } })
- );
- const [mainPanelNode] = useState(() =>
- createHtmlPortalNode({ attributes: { class: 'eui-fullHeight' } })
- );
-
- const isMobile = useIsWithinBreakpoints(['xs', 's']);
- const showFixedPanels = isMobile || !chart || chart.hidden;
- const { euiTheme } = useEuiTheme();
- const defaultTopPanelHeight = euiTheme.base * 12;
- const minMainPanelHeight = euiTheme.base * 10;
-
- const chartClassName =
- isMobile && chart && !chart.hidden
- ? css`
- height: ${defaultTopPanelHeight}px;
- `
- : 'eui-fullHeight';
-
- const panelsMode =
- chart || hits
- ? showFixedPanels
- ? ResizableLayoutMode.Static
- : ResizableLayoutMode.Resizable
- : ResizableLayoutMode.Single;
-
- const currentTopPanelHeight = topPanelHeight ?? defaultTopPanelHeight;
-
- return (
- <>
-
-
-
-
- {React.isValidElement(children)
- ? // @ts-expect-error upgrade typescript v4.9.5
- React.cloneElement(children, { isChartAvailable })
- : children}
-
- }
- flexPanel={}
- data-test-subj="unifiedHistogram"
- onFixedPanelSizeChange={onTopPanelHeightChange}
- />
- >
- );
-};
diff --git a/tsconfig.base.json b/tsconfig.base.json
index df3171643b36..4a07954a904f 100644
--- a/tsconfig.base.json
+++ b/tsconfig.base.json
@@ -2050,8 +2050,8 @@
"@kbn/unified-field-list/*": ["src/platform/packages/shared/kbn-unified-field-list/*"],
"@kbn/unified-field-list-examples-plugin": ["examples/unified_field_list_examples"],
"@kbn/unified-field-list-examples-plugin/*": ["examples/unified_field_list_examples/*"],
- "@kbn/unified-histogram-plugin": ["src/platform/plugins/shared/unified_histogram"],
- "@kbn/unified-histogram-plugin/*": ["src/platform/plugins/shared/unified_histogram/*"],
+ "@kbn/unified-histogram": ["src/platform/packages/shared/kbn-unified-histogram"],
+ "@kbn/unified-histogram/*": ["src/platform/packages/shared/kbn-unified-histogram/*"],
"@kbn/unified-search-plugin": ["src/platform/plugins/shared/unified_search"],
"@kbn/unified-search-plugin/*": ["src/platform/plugins/shared/unified_search/*"],
"@kbn/unified-tabs": ["src/platform/packages/shared/kbn-unified-tabs"],
diff --git a/x-pack/platform/plugins/private/discover_enhanced/ui_tests/tests/discover_cdp_perf.spec.ts b/x-pack/platform/plugins/private/discover_enhanced/ui_tests/tests/discover_cdp_perf.spec.ts
index e03d1c74e587..82f5ab976474 100644
--- a/x-pack/platform/plugins/private/discover_enhanced/ui_tests/tests/discover_cdp_perf.spec.ts
+++ b/x-pack/platform/plugins/private/discover_enhanced/ui_tests/tests/discover_cdp_perf.spec.ts
@@ -73,7 +73,6 @@ test.describe(
'kbn-ui-shared-deps-npm',
'lens',
'maps',
- 'unifiedHistogram',
'unifiedSearch',
]);
// Validate individual plugin bundle sizes
@@ -81,10 +80,6 @@ test.describe(
stats.plugins.find((p) => p.name === 'discover')?.totalSize,
`Total 'discover' bundles size should not exceed 650 KB`
).toBeLessThan(650 * 1024);
- expect(
- stats.plugins.find((p) => p.name === 'unifiedHistogram')?.totalSize,
- `Total 'unifiedHistogram' bundles size should not exceed 150 KB`
- ).toBeLessThan(150 * 1024);
expect(
stats.plugins.find((p) => p.name === 'unifiedSearch')?.totalSize,
`Total 'unifiedSearch' bundles size should not exceed 450 KB`
diff --git a/x-pack/platform/plugins/shared/dataset_quality/kibana.jsonc b/x-pack/platform/plugins/shared/dataset_quality/kibana.jsonc
index 471c25ec4952..e4e35a134c6d 100644
--- a/x-pack/platform/plugins/shared/dataset_quality/kibana.jsonc
+++ b/x-pack/platform/plugins/shared/dataset_quality/kibana.jsonc
@@ -34,7 +34,6 @@
"telemetry"
],
"requiredBundles": [
- "unifiedHistogram",
"discover"
],
"extraPublicDirs": [
diff --git a/x-pack/platform/plugins/shared/dataset_quality/public/components/dataset_quality_details/overview/document_trends/index.tsx b/x-pack/platform/plugins/shared/dataset_quality/public/components/dataset_quality_details/overview/document_trends/index.tsx
index 856cc251d6d6..e0a0eaa84166 100644
--- a/x-pack/platform/plugins/shared/dataset_quality/public/components/dataset_quality_details/overview/document_trends/index.tsx
+++ b/x-pack/platform/plugins/shared/dataset_quality/public/components/dataset_quality_details/overview/document_trends/index.tsx
@@ -24,7 +24,7 @@ import {
import { css } from '@emotion/react';
import { i18n } from '@kbn/i18n';
import { FormattedMessage } from '@kbn/i18n-react';
-import { UnifiedBreakdownFieldSelector } from '@kbn/unified-histogram-plugin/public';
+import { UnifiedBreakdownFieldSelector } from '@kbn/unified-histogram';
import React, { useCallback } from 'react';
import {
discoverAriaText,
diff --git a/x-pack/platform/plugins/shared/dataset_quality/tsconfig.json b/x-pack/platform/plugins/shared/dataset_quality/tsconfig.json
index d28adf112457..7d4fb442f54d 100644
--- a/x-pack/platform/plugins/shared/dataset_quality/tsconfig.json
+++ b/x-pack/platform/plugins/shared/dataset_quality/tsconfig.json
@@ -32,7 +32,6 @@
"@kbn/unified-search-plugin",
"@kbn/timerange",
"@kbn/lens-plugin",
- "@kbn/unified-histogram-plugin",
"@kbn/data-views-plugin",
"@kbn/shared-ux-error-boundary",
"@kbn/es-query",
@@ -58,7 +57,8 @@
"@kbn/logging",
"@kbn/ui-theme",
"@kbn/react-hooks",
- "@kbn/charts-theme"
+ "@kbn/charts-theme",
+ "@kbn/unified-histogram"
],
"exclude": [
"target/**/*"
diff --git a/x-pack/solutions/security/plugins/security_solution/public/timelines/components/timeline/tabs/esql/customizations/use_histogram_customizations.tsx b/x-pack/solutions/security/plugins/security_solution/public/timelines/components/timeline/tabs/esql/customizations/use_histogram_customizations.tsx
index 783c667ee720..a1da8e298fd3 100644
--- a/x-pack/solutions/security/plugins/security_solution/public/timelines/components/timeline/tabs/esql/customizations/use_histogram_customizations.tsx
+++ b/x-pack/solutions/security/plugins/security_solution/public/timelines/components/timeline/tabs/esql/customizations/use_histogram_customizations.tsx
@@ -11,7 +11,7 @@ import type {
MultiClickTriggerEvent,
} from '@kbn/charts-plugin/public';
import type { CustomizationCallback } from '@kbn/discover-plugin/public';
-import type { UnifiedHistogramContainerProps } from '@kbn/unified-histogram-plugin/public';
+import type { UseUnifiedHistogramProps } from '@kbn/unified-histogram';
import { ACTION_GLOBAL_APPLY_FILTER } from '@kbn/unified-search-plugin/public';
import { useCallback } from 'react';
import { EsqlInTimelineTrigger } from '../../../../../../app/actions/constants';
@@ -42,7 +42,7 @@ export const useHistogramCustomization = () => {
services: { customDataService: discoverDataService, uiActions },
} = useKibana();
- const onFilterCallback: UnifiedHistogramContainerProps['onFilter'] = useCallback(
+ const onFilterCallback: UseUnifiedHistogramProps['onFilter'] = useCallback(
async (eventData: WithPreventableEvent) => {
if (eventData.preventDefault) eventData.preventDefault();
let filters;
@@ -78,7 +78,7 @@ export const useHistogramCustomization = () => {
[uiActions, discoverDataService.actions]
);
- const onBrushEndCallback: UnifiedHistogramContainerProps['onBrushEnd'] = useCallback(
+ const onBrushEndCallback: UseUnifiedHistogramProps['onBrushEnd'] = useCallback(
(data: WithPreventableEvent) => {
discoverDataService.query.timefilter.timefilter.setTime({
from: new Date(data.range[0]).toISOString(),
diff --git a/x-pack/solutions/security/plugins/security_solution/tsconfig.json b/x-pack/solutions/security/plugins/security_solution/tsconfig.json
index 657d7d3b3f7d..7af2b988f2ec 100644
--- a/x-pack/solutions/security/plugins/security_solution/tsconfig.json
+++ b/x-pack/solutions/security/plugins/security_solution/tsconfig.json
@@ -157,7 +157,6 @@
"@kbn/data-view-editor-plugin",
"@kbn/alerts-ui-shared",
"@kbn/saved-search-plugin",
- "@kbn/unified-histogram-plugin",
"@kbn/navigation-plugin",
"@kbn/core-logging-server-mocks",
"@kbn/core-lifecycle-browser",
@@ -249,5 +248,6 @@
"@kbn/core-chrome-browser",
"@kbn/actions-types",
"@kbn/triggers-actions-ui-types",
+ "@kbn/unified-histogram",
]
}
diff --git a/yarn.lock b/yarn.lock
index 76221a44e8e2..2fae0c2b6ee7 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -7795,7 +7795,7 @@
version "0.0.0"
uid ""
-"@kbn/unified-histogram-plugin@link:src/platform/plugins/shared/unified_histogram":
+"@kbn/unified-histogram@link:src/platform/packages/shared/kbn-unified-histogram":
version "0.0.0"
uid ""