diff --git a/src/plugins/discover/public/components/discover_grid_flyout/discover_grid_flyout.test.tsx b/src/plugins/discover/public/components/discover_grid_flyout/discover_grid_flyout.test.tsx
index 9593c6c81c31e..d1ff933ecad8f 100644
--- a/src/plugins/discover/public/components/discover_grid_flyout/discover_grid_flyout.test.tsx
+++ b/src/plugins/discover/public/components/discover_grid_flyout/discover_grid_flyout.test.tsx
@@ -23,6 +23,18 @@ import { act } from 'react-dom/test-utils';
import { ReactWrapper } from 'enzyme';
import { setUnifiedDocViewerServices } from '@kbn/unified-doc-viewer-plugin/public/plugin';
import { mockUnifiedDocViewerServices } from '@kbn/unified-doc-viewer-plugin/public/__mocks__';
+import { FlyoutCustomization, useDiscoverCustomization } from '../../customizations';
+import { EuiFlexItem } from '@elastic/eui';
+
+const mockFlyoutCustomization: FlyoutCustomization = {
+ id: 'flyout',
+ actions: {},
+};
+
+jest.mock('../../customizations', () => ({
+ ...jest.requireActual('../../customizations'),
+ useDiscoverCustomization: jest.fn(),
+}));
const waitNextTick = () => new Promise((resolve) => setTimeout(resolve, 0));
@@ -94,6 +106,13 @@ describe('Discover flyout', function () {
return { component, props };
};
+ beforeEach(() => {
+ mockFlyoutCustomization.actions.defaultActions = undefined;
+ jest.clearAllMocks();
+
+ (useDiscoverCustomization as jest.Mock).mockImplementation(() => mockFlyoutCustomization);
+ });
+
it('should be rendered correctly using an data view without timefield', async () => {
const { component, props } = await mountComponent({});
@@ -206,4 +225,45 @@ describe('Discover flyout', function () {
const flyoutTitle = findTestSubject(component, 'docTableRowDetailsTitle');
expect(flyoutTitle.text()).toBe('Expanded row');
});
+
+ describe('when customizations actions exists', () => {
+ it('should display actions added by getActionItems', async () => {
+ mockFlyoutCustomization.actions = {
+ getActionItems: jest.fn(() => [
+ {
+ id: 'action-item-1',
+ enabled: true,
+ Content: () => Action 1,
+ },
+ {
+ id: 'action-item-2',
+ enabled: true,
+ Content: () => Action 2,
+ },
+ ]),
+ };
+
+ const { component } = await mountComponent({});
+
+ const action1 = findTestSubject(component, 'customActionItem1');
+ const action2 = findTestSubject(component, 'customActionItem2');
+
+ expect(action1.text()).toBe('Action 1');
+ expect(action2.text()).toBe('Action 2');
+ });
+
+ it('should allow disabling default actions', async () => {
+ mockFlyoutCustomization.actions = {
+ defaultActions: {
+ viewSingleDocument: { disabled: true },
+ viewSurroundingDocument: { disabled: true },
+ },
+ };
+
+ const { component } = await mountComponent({});
+
+ const singleDocumentView = findTestSubject(component, 'docTableRowAction');
+ expect(singleDocumentView.length).toBeFalsy();
+ });
+ });
});
diff --git a/src/plugins/discover/public/components/discover_grid_flyout/discover_grid_flyout.tsx b/src/plugins/discover/public/components/discover_grid_flyout/discover_grid_flyout.tsx
index a9130df52738e..7c0598abbfe18 100644
--- a/src/plugins/discover/public/components/discover_grid_flyout/discover_grid_flyout.tsx
+++ b/src/plugins/discover/public/components/discover_grid_flyout/discover_grid_flyout.tsx
@@ -15,23 +15,19 @@ import {
EuiFlyout,
EuiFlyoutBody,
EuiFlyoutHeader,
- EuiIconTip,
EuiTitle,
- EuiButtonEmpty,
- EuiText,
EuiSpacer,
EuiPortal,
EuiPagination,
- EuiHideFor,
keys,
} from '@elastic/eui';
import type { Filter, Query, AggregateQuery } from '@kbn/es-query';
import type { DataTableRecord } from '@kbn/discover-utils/types';
import type { DocViewFilterFn } from '@kbn/unified-doc-viewer/types';
import { UnifiedDocViewer } from '@kbn/unified-doc-viewer-plugin/public';
-import { useNavigationProps } from '../../hooks/use_navigation_props';
import { useDiscoverServices } from '../../hooks/use_discover_services';
import { isTextBasedQuery } from '../../application/main/utils/is_text_based_query';
+import { useFlyoutActions } from './use_flyout_actions';
export interface DiscoverGridFlyoutProps {
savedSearchId?: string;
@@ -104,9 +100,14 @@ export function DiscoverGridFlyout({
[activePage, setPage]
);
- const { singleDocHref, contextViewHref, onOpenSingleDoc, onOpenContextView } = useNavigationProps(
- { dataView, rowIndex: hit.raw._index, rowId: hit.raw._id, columns, filters, savedSearchId }
- );
+ const { flyoutActions } = useFlyoutActions({
+ dataView,
+ rowIndex: hit.raw._index,
+ rowId: hit.raw._id,
+ columns,
+ filters,
+ savedSearchId,
+ });
return (
@@ -136,77 +137,8 @@ export function DiscoverGridFlyout({
- {!isPlainRecord && (
- <>
-
-
-
-
- {i18n.translate('discover.grid.tableRow.viewText', {
- defaultMessage: 'View:',
- })}
-
-
-
-
-
- {/* eslint-disable-next-line @elastic/eui/href-or-on-click */}
-
- {i18n.translate('discover.grid.tableRow.viewSingleDocumentLinkTextSimple', {
- defaultMessage: 'Single document',
- })}
-
-
- {dataView.isTimeBased() && dataView.id && (
-
-
- {/* eslint-disable-next-line @elastic/eui/href-or-on-click */}
-
- {i18n.translate(
- 'discover.grid.tableRow.viewSurroundingDocumentsLinkTextSimple',
- {
- defaultMessage: 'Surrounding documents',
- }
- )}
-
-
-
-
-
-
- )}
- >
- )}
+ {!isPlainRecord &&
+ flyoutActions.map((action) => action.enabled && )}
{activePage !== -1 && (
;
+ href: string;
+}
+
+const staticViewDocumentItem = {
+ id: 'viewDocument',
+ enabled: true,
+ Content: () => ,
+};
+
+export const useFlyoutActions = (navigationProps: UseNavigationProps) => {
+ const { dataView } = navigationProps;
+ const { singleDocHref, contextViewHref, onOpenSingleDoc, onOpenContextView } =
+ useNavigationProps(navigationProps);
+
+ const flyoutCustomization = useDiscoverCustomization('flyout');
+
+ const {
+ viewSingleDocument = { disabled: false },
+ viewSurroundingDocument = { disabled: false },
+ } = flyoutCustomization?.actions?.defaultActions ?? {};
+ const customActions = [...(flyoutCustomization?.actions?.getActionItems?.() ?? [])];
+
+ const flyoutActions = [
+ {
+ id: 'singleDocument',
+ enabled: !viewSingleDocument.disabled,
+ Content: () => ,
+ },
+ {
+ id: 'surroundingDocument',
+ enabled: Boolean(!viewSurroundingDocument.disabled && dataView.isTimeBased() && dataView.id),
+ Content: () => ,
+ },
+ ...customActions,
+ ];
+
+ const hasEnabledActions = flyoutActions.some((action) => action.enabled);
+
+ if (hasEnabledActions) {
+ flyoutActions.unshift(staticViewDocumentItem);
+ }
+
+ return { flyoutActions, hasEnabledActions };
+};
+
+const ViewDocument = () => {
+ return (
+
+
+
+
+ {i18n.translate('discover.grid.tableRow.viewText', {
+ defaultMessage: 'View:',
+ })}
+
+
+
+
+ );
+};
+
+const SingleDocument = (props: FlyoutActionProps) => {
+ return (
+
+
+ {i18n.translate('discover.grid.tableRow.viewSingleDocumentLinkTextSimple', {
+ defaultMessage: 'Single document',
+ })}
+
+
+ );
+};
+
+const SurroundingDocuments = (props: FlyoutActionProps) => {
+ return (
+
+
+
+ {i18n.translate('discover.grid.tableRow.viewSurroundingDocumentsLinkTextSimple', {
+ defaultMessage: 'Surrounding documents',
+ })}
+
+
+
+
+
+
+ );
+};
diff --git a/src/plugins/discover/public/customizations/customization_service.ts b/src/plugins/discover/public/customizations/customization_service.ts
index 0b57ba37e07dc..15175c8bad1ae 100644
--- a/src/plugins/discover/public/customizations/customization_service.ts
+++ b/src/plugins/discover/public/customizations/customization_service.ts
@@ -8,12 +8,14 @@
import { filter, map, Observable, startWith, Subject } from 'rxjs';
import type {
+ FlyoutCustomization,
SearchBarCustomization,
TopNavCustomization,
UnifiedHistogramCustomization,
} from './customization_types';
export type DiscoverCustomization =
+ | FlyoutCustomization
| SearchBarCustomization
| TopNavCustomization
| UnifiedHistogramCustomization;
diff --git a/src/plugins/discover/public/customizations/customization_types/flyout_customization.ts b/src/plugins/discover/public/customizations/customization_types/flyout_customization.ts
new file mode 100644
index 0000000000000..6ec0fe9dec60a
--- /dev/null
+++ b/src/plugins/discover/public/customizations/customization_types/flyout_customization.ts
@@ -0,0 +1,30 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0 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 or the Server
+ * Side Public License, v 1.
+ */
+
+export interface FlyoutDefaultActionItem {
+ disabled?: boolean;
+}
+
+export interface FlyoutDefaultActions {
+ viewSingleDocument?: FlyoutDefaultActionItem;
+ viewSurroundingDocument?: FlyoutDefaultActionItem;
+}
+
+export interface FlyoutActionItem {
+ id: string;
+ Content: React.ElementType;
+ enabled: boolean;
+}
+
+export interface FlyoutCustomization {
+ id: 'flyout';
+ actions: {
+ defaultActions?: FlyoutDefaultActions;
+ getActionItems?: () => FlyoutActionItem[];
+ };
+}
diff --git a/src/plugins/discover/public/customizations/customization_types/index.ts b/src/plugins/discover/public/customizations/customization_types/index.ts
index e920a68574b93..effb7fccf207c 100644
--- a/src/plugins/discover/public/customizations/customization_types/index.ts
+++ b/src/plugins/discover/public/customizations/customization_types/index.ts
@@ -6,6 +6,7 @@
* Side Public License, v 1.
*/
+export * from './flyout_customization';
export * from './search_bar_customization';
export * from './top_nav_customization';
export * from './histogram_customization';
diff --git a/src/plugins/discover/public/index.ts b/src/plugins/discover/public/index.ts
index ca3c58a4d2899..42033c2ebfdb5 100644
--- a/src/plugins/discover/public/index.ts
+++ b/src/plugins/discover/public/index.ts
@@ -25,6 +25,7 @@ export type {
RegisterCustomizationProfile,
DiscoverCustomization,
DiscoverCustomizationService,
+ FlyoutCustomization,
SearchBarCustomization,
UnifiedHistogramCustomization,
TopNavCustomization,
diff --git a/x-pack/plugins/log_explorer/public/customizations/log_explorer_profile.tsx b/x-pack/plugins/log_explorer/public/customizations/log_explorer_profile.tsx
index ee8f7ffbc9779..c5d98b9b24101 100644
--- a/x-pack/plugins/log_explorer/public/customizations/log_explorer_profile.tsx
+++ b/x-pack/plugins/log_explorer/public/customizations/log_explorer_profile.tsx
@@ -95,6 +95,19 @@ export const createLogExplorerProfileCustomizations =
},
});
+ /**
+ * Hide flyout actions to prevent rendering hard-coded actions.
+ */
+ customizations.set({
+ id: 'flyout',
+ actions: {
+ defaultActions: {
+ viewSingleDocument: { disabled: true },
+ viewSurroundingDocument: { disabled: true },
+ },
+ },
+ });
+
return () => {
if (stateSubscription) {
stateSubscription.unsubscribe();