diff --git a/public/components/metrics/index.tsx b/public/components/metrics/index.tsx index 2198db97b..348e79f8c 100644 --- a/public/components/metrics/index.tsx +++ b/public/components/metrics/index.tsx @@ -3,7 +3,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -import { EuiPage, EuiPageBody, EuiResizableContainer } from '@elastic/eui'; +import { EuiPage, EuiPageBody, EuiResizableContainer, EuiSpacer } from '@elastic/eui'; import debounce from 'lodash/debounce'; import React, { useEffect, useMemo, useState } from 'react'; import { useDispatch } from 'react-redux'; @@ -115,11 +115,17 @@ export const Home = ({ +
{(EuiResizablePanel, EuiResizableButton) => ( <> - +
- - - + + + + + +
-
- + + diff --git a/public/components/metrics/top_menu/__tests__/__snapshots__/metrics_export_panel.test.tsx.snap b/public/components/metrics/top_menu/__tests__/__snapshots__/metrics_export_panel.test.tsx.snap index 9ea61d751..3a5bc32ea 100644 --- a/public/components/metrics/top_menu/__tests__/__snapshots__/metrics_export_panel.test.tsx.snap +++ b/public/components/metrics/top_menu/__tests__/__snapshots__/metrics_export_panel.test.tsx.snap @@ -68,298 +68,26 @@ exports[`Export Metrics Panel Component renders Export Metrics Panel Component 1 } } > - -
-
- - - -
-
- -
- - -
-
-
-

- Select dashboards/applications -

- -
- -
-
- -
- -
- - - -
-
-
-
- - -
- - -
- Search existing dashboards or applications by name -
-
-
-
- + SAVE THE VIEW AS VISUALIZATION + + + +
+
- Metric Name #1 + Metric 1
@@ -481,7 +209,7 @@ exports[`Export Metrics Panel Component renders Export Metrics Panel Component 1 fullWidth={false} hasChildLabel={true} hasEmptyLabelSpace={false} - label="Metric Name #2" + label="Metric 2" labelType="label" >
- Metric Name #2 + Metric 2
@@ -554,6 +282,325 @@ exports[`Export Metrics Panel Component renders Export Metrics Panel Component 1
+ +
+ +
+ +
+

+ + Add to custom operational dashboards or applications. + +

+
+
+
+
+ +
+ +
+
+ + + +
+
+ +
+ + +
+
+
+

+ Select dashboards/applications +

+ +
+ +
+
+ +
+ +
+ + + +
+
+
+
+ + +
+ +
+
+ +
+ +
+
diff --git a/public/components/metrics/top_menu/__tests__/__snapshots__/top_menu.test.tsx.snap b/public/components/metrics/top_menu/__tests__/__snapshots__/top_menu.test.tsx.snap index fb8bd0c1b..de619ec37 100644 --- a/public/components/metrics/top_menu/__tests__/__snapshots__/top_menu.test.tsx.snap +++ b/public/components/metrics/top_menu/__tests__/__snapshots__/top_menu.test.tsx.snap @@ -14,11 +14,12 @@ exports[`Metrics Top Menu Component renders Top Menu Component when enabled 1`] >
} + compressed={true} fullWidth={false} prepend="Span Interval" >
- +
- - -
- -
+ - - } +
- - +
+ - - - } - closePopover={[Function]} - display="inlineBlock" - hasArrow={true} - isOpen={false} - ownFocus={true} - panelPaddingSize="s" - > -
- + + + } - } + closePopover={[Function]} + display="inlineBlock" + hasArrow={true} + isOpen={false} + ownFocus={true} + panelPaddingSize="s" + > +
+
+ + + +
+
+ + +
- +
+ + +
+
+
+
+ + +
+ + + + - - - - - + + + + + + + - - - - + + Refresh + + + + + + + + + + +
+
+
+
+
+
+
+ +
+ + + + + } + closePopover={[Function]} + display="inlineBlock" + hasArrow={true} + isOpen={false} + ownFocus={true} + panelPaddingSize="m" + > +
+
+ + + + - -
-
-
- -
- } - iconType={false} - isCustom={true} - startDateControl={
} - > -
- + + + + +
- - -
-
- -
-
- -
- - - - - - - - - - - -
-
-
-
-
-
-
- -
- - - - } - closePopover={[Function]} - display="inlineBlock" - hasArrow={true} - isOpen={false} - ownFocus={true} - panelPaddingSize="m" - > -
-
- - - - - - - -
+
+
+ +
+
- - - +
+
+
diff --git a/public/components/metrics/top_menu/__tests__/metrics_export.test.tsx b/public/components/metrics/top_menu/__tests__/metrics_export.test.tsx index 5e017873e..5e18332a9 100644 --- a/public/components/metrics/top_menu/__tests__/metrics_export.test.tsx +++ b/public/components/metrics/top_menu/__tests__/metrics_export.test.tsx @@ -42,6 +42,7 @@ const defaultInitialState = { refresh: 0, // set to new Date() to trigger }; +// eslint-disable-next-line jest/no-export export function renderWithMetricsProviders( ui: React.ReactElement, { @@ -54,6 +55,7 @@ export function renderWithMetricsProviders( ...renderOptions }: ExtendedRenderOptions = {} ) { + // eslint-disable-next-line @typescript-eslint/no-unused-vars function Wrapper({ children }: PropsWithChildren<{}>): JSX.Element { return {children}; } @@ -145,7 +147,8 @@ describe('Export Metrics Panel Component', () => { expect(saveButton).toBeInTheDocument(); fireEvent.click(saveButton); - expect(await screen.findByText('Custom operational dashboards/application')); + // eslint-disable-next-line jest/valid-expect + expect(await screen.findByText('Dashboards and applications - optional')); const dialog = screen.getByRole('dialog'); fireEvent.keyDown(dialog, { key: 'Escape', code: 'Escape' }); diff --git a/public/components/metrics/top_menu/metrics_export.tsx b/public/components/metrics/top_menu/metrics_export.tsx index e3a9e92ed..1ca548643 100644 --- a/public/components/metrics/top_menu/metrics_export.tsx +++ b/public/components/metrics/top_menu/metrics_export.tsx @@ -14,7 +14,7 @@ import { } from '@elastic/eui'; import { I18nProvider } from '@osd/i18n/react'; import max from 'lodash/max'; -import React, { useEffect } from 'react'; +import React, { useEffect, useState } from 'react'; import { render, unmountComponentAtNode } from 'react-dom'; import { useSelector } from 'react-redux'; import semver from 'semver'; @@ -50,6 +50,8 @@ const Savebutton = ({ }) => { return ( { setIsPanelOpen((staleState) => !staleState); @@ -57,25 +59,41 @@ const Savebutton = ({ data-test-subj="metrics__saveManagementPopover" iconType="arrowDown" > - Save + Save as visualization ); }; +const HeaderControlledPopoverWrapper = ({ children }: { children: React.ReactElement }) => { + const HeaderControl = coreRefs.navigation?.ui.HeaderControl; + const showActionsInHeader = coreRefs.chrome?.navGroup.getNavGroupEnabled(); + + if (showActionsInHeader && HeaderControl) { + return ( + + ); + } + + return <>{children}; +}; + const MetricsExportPopOver = () => { const availableObservabilityDashboards = useSelector(selectPanelList); - const [availableDashboards, setAvailableDashboards] = React.useState([]); - const [osdCoreDashboards, setOsdCoreDashboards] = React.useState([]); + const [availableDashboards, setAvailableDashboards] = useState([]); + const [osdCoreDashboards, setOsdCoreDashboards] = useState([]); - const [isPanelOpen, setIsPanelOpen] = React.useState(false); + const [isPanelOpen, setIsPanelOpen] = useState(false); const selectedMetrics = useSelector(selectedMetricsSelector); const selectedMetricsIds = useSelector(selectedMetricsIdsSelector); const dateSpanFilter = useSelector(dateSpanFilterSelector); - const [metricsToExport, setMetricsToExport] = React.useState([]); + const [metricsToExport, setMetricsToExport] = useState([]); - const [selectedPanelOptions, setSelectedPanelOptions] = React.useState([]); + const [selectedPanelOptions, setSelectedPanelOptions] = useState([]); const { toasts } = coreRefs; @@ -368,44 +386,46 @@ const MetricsExportPopOver = () => { }; return ( - } - isOpen={isPanelOpen} - closePopover={() => setIsPanelOpen(false)} - > - - - - - setIsPanelOpen(false)} - data-test-subj="metrics__SaveCancel" - > - Cancel - - - - { - handleSavingObjects().then(() => setIsPanelOpen(false)); - }} - data-test-subj="metrics__SaveConfirm" - > - Save - - - - - + + } + isOpen={isPanelOpen} + closePopover={() => setIsPanelOpen(false)} + > + + + + + setIsPanelOpen(false)} + data-test-subj="metrics__SaveCancel" + > + Cancel + + + + { + handleSavingObjects().then(() => setIsPanelOpen(false)); + }} + data-test-subj="metrics__SaveConfirm" + > + Save + + + + + + ); }; diff --git a/public/components/metrics/top_menu/metrics_export_panel.tsx b/public/components/metrics/top_menu/metrics_export_panel.tsx index 3884a55c2..40940911b 100644 --- a/public/components/metrics/top_menu/metrics_export_panel.tsx +++ b/public/components/metrics/top_menu/metrics_export_panel.tsx @@ -3,15 +3,19 @@ * SPDX-License-Identifier: Apache-2.0 */ -import React, { useEffect } from 'react'; import { EuiComboBox, EuiFieldText, EuiFlexGroup, - EuiFormRow, EuiFlexItem, EuiForm, + EuiFormRow, + EuiHorizontalRule, + EuiSpacer, + EuiText, + EuiTitle, } from '@elastic/eui'; +import React, { useEffect } from 'react'; import { useDispatch } from 'react-redux'; import { MetricType } from '../../../../common/types/metrics'; import { fetchPanels } from '../../../../public/components/custom_panels/redux/panel_slice'; @@ -53,37 +57,27 @@ export const MetricsExportPanel = ({ return (
- - { - setSelectedPanelOptions(newOptions); - }} - selectedOptions={selectedPanelOptions} - options={ - availableDashboards?.map((option: any) => { - return { - panel: option, - label: option.title, - }; - }) ?? [] - } - isClearable={true} - data-test-subj="eventExplorer__querySaveComboBox" - /> - + +

SAVE THE VIEW AS VISUALIZATION

+
+ {metricsToExport.length > 0 && ( -
+
{metricsToExport.map((metaData: any, index: number) => { return ( - + )} + + + {!(metricsToExport.length > 0) && ( + + +

+ Save the view as visualization. You can add it to custom operational dashboards or + applications. +

+
+ +
+ )} + + {metricsToExport.length > 0 && ( + + +

+ Add to custom operational dashboards or applications. +

+
+
+ )} + + + + { + setSelectedPanelOptions(newOptions); + }} + selectedOptions={selectedPanelOptions} + options={ + availableDashboards?.map((option: any) => ({ + panel: option, + label: option.title, + })) ?? [] + } + isClearable={true} + data-test-subj="eventExplorer__querySaveComboBox" + /> + + +
); }; diff --git a/public/components/metrics/top_menu/top_menu.scss b/public/components/metrics/top_menu/top_menu.scss index ff247f31d..0906b1136 100644 --- a/public/components/metrics/top_menu/top_menu.scss +++ b/public/components/metrics/top_menu/top_menu.scss @@ -14,3 +14,7 @@ .metrics-search-bar-datepicker { width: 500px; } + +.resolutionSelectOption { + line-height: inherit; +} diff --git a/public/components/metrics/top_menu/top_menu.tsx b/public/components/metrics/top_menu/top_menu.tsx index 521300b5f..8ebc5d87a 100644 --- a/public/components/metrics/top_menu/top_menu.tsx +++ b/public/components/metrics/top_menu/top_menu.tsx @@ -26,10 +26,11 @@ export const TopMenu = () => { return ( dateSpanFilter && ( <> - +
{ />
- - dispatch(setDateSpan(dateSpan))} - recentlyUsedRanges={dateSpanFilter.recentlyUsedRanges} - /> - - + + + dispatch(setDateSpan(dateSpan))} + recentlyUsedRanges={dateSpanFilter.recentlyUsedRanges} + /> + + + + +
diff --git a/public/framework/core_refs.ts b/public/framework/core_refs.ts index 59315c2fa..7759d65ab 100644 --- a/public/framework/core_refs.ts +++ b/public/framework/core_refs.ts @@ -17,6 +17,7 @@ import { DashboardStart } from '../../../../src/plugins/dashboard/public'; import { DataSourcePluginStart } from '../../../../src/plugins/data_source/public'; import PPLService from '../services/requests/ppl'; import { DataSourceStart } from '../../../../src/plugins/data/public/data_sources/datasource_services/types'; +import { NavigationPublicPluginStart } from '../../../../src/plugins/navigation/public'; class CoreRefs { private static _instance: CoreRefs; @@ -36,6 +37,7 @@ class CoreRefs { public overlays?: OverlayStart; public dataSource?: DataSourcePluginStart; public dataSources?: DataSourceStart; + public navigation?: NavigationPublicPluginStart; private constructor() { // ... } diff --git a/public/plugin.tsx b/public/plugin.tsx index b2ee97850..99033e0bf 100644 --- a/public/plugin.tsx +++ b/public/plugin.tsx @@ -448,6 +448,7 @@ export class ObservabilityPlugin coreRefs.summarizeEnabled = this.config.summarize.enabled; coreRefs.overlays = core.overlays; coreRefs.dataSource = startDeps.dataSource; + coreRefs.navigation = startDeps.navigation; const { dataSourceService, dataSourceFactory } = startDeps.data.dataSources; dataSourceFactory.registerDataSourceType(S3_DATA_SOURCE_TYPE, S3DataSource);