diff --git a/src/plugins/dashboard/public/dashboard_actions/_dashboard_actions_strings.ts b/src/plugins/dashboard/public/dashboard_actions/_dashboard_actions_strings.ts index 3490ed4b06238..eb56b39bf71a9 100644 --- a/src/plugins/dashboard/public/dashboard_actions/_dashboard_actions_strings.ts +++ b/src/plugins/dashboard/public/dashboard_actions/_dashboard_actions_strings.ts @@ -51,7 +51,7 @@ export const dashboardAddToLibraryActionStrings = { export const dashboardClonePanelActionStrings = { getDisplayName: () => i18n.translate('dashboard.panel.clonePanel', { - defaultMessage: 'Clone panel', + defaultMessage: 'Duplicate', }), getClonedTag: () => i18n.translate('dashboard.panel.title.clonedTag', { @@ -59,7 +59,7 @@ export const dashboardClonePanelActionStrings = { }), getSuccessMessage: () => i18n.translate('dashboard.panel.clonedToast', { - defaultMessage: 'Cloned panel', + defaultMessage: 'Duplicated panel', }), }; @@ -70,14 +70,14 @@ export const dashboardExpandPanelActionStrings = { }), getMaximizeTitle: () => i18n.translate('dashboard.actions.toggleExpandPanelMenuItem.notExpandedDisplayName', { - defaultMessage: 'Maximize panel', + defaultMessage: 'Maximize', }), }; export const dashboardExportCsvActionStrings = { getDisplayName: () => i18n.translate('dashboard.actions.DownloadCreateDrilldownAction.displayName', { - defaultMessage: 'Download as CSV', + defaultMessage: 'Download CSV', }), getUntitledFilename: () => i18n.translate('dashboard.actions.downloadOptionsUnsavedFilename', { @@ -118,35 +118,6 @@ export const dashboardLibraryNotificationStrings = { }), }; -export const dashboardReplacePanelActionStrings = { - getDisplayName: () => - i18n.translate('dashboard.panel.removePanel.replacePanel', { - defaultMessage: 'Replace panel', - }), - getFlyoutHeader: (panelName?: string) => - i18n.translate('dashboard.panel.replacePanel.flyoutHeader', { - defaultMessage: 'Replace panel {panelName} with:', - values: { - panelName: `'${panelName}'`, - }, - }), - getSuccessMessage: (savedObjectName?: string) => - savedObjectName - ? i18n.translate('dashboard.addPanel.savedObjectAddedToContainerSuccessMessageTitle', { - defaultMessage: '{savedObjectName} was added', - values: { - savedObjectName: `'${savedObjectName}'`, - }, - }) - : i18n.translate('dashboard.addPanel.panelAddedToContainerSuccessMessageTitle', { - defaultMessage: 'A panel was added', - }), - getNoMatchingObjectsMessage: () => - i18n.translate('dashboard.addPanel.noMatchingObjectsMessage', { - defaultMessage: 'No matching objects found.', - }), -}; - export const dashboardFilterNotificationActionStrings = { getDisplayName: () => i18n.translate('dashboard.panel.filters', { diff --git a/src/plugins/dashboard/public/dashboard_actions/add_to_library_action.tsx b/src/plugins/dashboard/public/dashboard_actions/add_to_library_action.tsx index ce6398788d947..90a0667a87c5a 100644 --- a/src/plugins/dashboard/public/dashboard_actions/add_to_library_action.tsx +++ b/src/plugins/dashboard/public/dashboard_actions/add_to_library_action.tsx @@ -57,7 +57,7 @@ const isApiCompatible = (api: unknown | null): api is AddPanelToLibraryActionApi export class AddToLibraryAction implements Action { public readonly type = ACTION_ADD_TO_LIBRARY; public readonly id = ACTION_ADD_TO_LIBRARY; - public order = 15; + public order = 8; private toastsService; diff --git a/src/plugins/dashboard/public/dashboard_actions/expand_panel_action.test.tsx b/src/plugins/dashboard/public/dashboard_actions/expand_panel_action.test.tsx index 516d126a39989..6ff1773ff610e 100644 --- a/src/plugins/dashboard/public/dashboard_actions/expand_panel_action.test.tsx +++ b/src/plugins/dashboard/public/dashboard_actions/expand_panel_action.test.tsx @@ -46,7 +46,7 @@ describe('Expand panel action', () => { }); it('returns the correct display name based on expanded panel id', async () => { - expect(await action.getDisplayName(context)).toBe('Maximize panel'); + expect(await action.getDisplayName(context)).toBe('Maximize'); context.embeddable.parentApi.expandedPanelId = new BehaviorSubject( 'superPanelId' ); diff --git a/src/plugins/dashboard/public/dashboard_actions/export_csv_action.tsx b/src/plugins/dashboard/public/dashboard_actions/export_csv_action.tsx index 45ec7c7db8013..c834ab460128b 100644 --- a/src/plugins/dashboard/public/dashboard_actions/export_csv_action.tsx +++ b/src/plugins/dashboard/public/dashboard_actions/export_csv_action.tsx @@ -40,7 +40,7 @@ const isApiCompatible = (api: unknown | null): api is ExportCsvActionApi => export class ExportCSVAction implements Action { public readonly id = ACTION_EXPORT_CSV; public readonly type = ACTION_EXPORT_CSV; - public readonly order = 5; + public readonly order = 18; // right after Export in discover which is 19 private fieldFormats; private uiSettings; diff --git a/src/plugins/dashboard/public/dashboard_actions/index.ts b/src/plugins/dashboard/public/dashboard_actions/index.ts index 2085e9f91bafd..ecffeaa5643ae 100644 --- a/src/plugins/dashboard/public/dashboard_actions/index.ts +++ b/src/plugins/dashboard/public/dashboard_actions/index.ts @@ -8,10 +8,6 @@ import { CoreStart } from '@kbn/core/public'; import { CONTEXT_MENU_TRIGGER, PANEL_NOTIFICATION_TRIGGER } from '@kbn/embeddable-plugin/public'; -import { - getSavedObjectFinder, - SavedObjectFinderProps, -} from '@kbn/saved-objects-finder-plugin/public'; import { DashboardStartDependencies } from '../plugin'; import { AddToLibraryAction } from './add_to_library_action'; @@ -22,7 +18,6 @@ import { ExpandPanelAction } from './expand_panel_action'; import { ExportCSVAction } from './export_csv_action'; import { FiltersNotificationAction } from './filters_notification_action'; import { LegacyLibraryNotificationAction } from './legacy_library_notification_action'; -import { ReplacePanelAction } from './replace_panel_action'; import { UnlinkFromLibraryAction } from './unlink_from_library_action'; import { LegacyUnlinkFromLibraryAction } from './legacy_unlink_from_library_action'; import { LibraryNotificationAction } from './library_notification_action'; @@ -33,28 +28,16 @@ interface BuildAllDashboardActionsProps { plugins: DashboardStartDependencies; } -export type ReplacePanelSOFinder = (props: Omit) => JSX.Element; - export const buildAllDashboardActions = async ({ core, plugins, allowByValueEmbeddables, }: BuildAllDashboardActionsProps) => { - const { uiActions, share, savedObjectsTaggingOss, contentManagement } = plugins; + const { uiActions, share } = plugins; const clonePanelAction = new ClonePanelAction(); uiActions.registerAction(clonePanelAction); uiActions.attachAction(CONTEXT_MENU_TRIGGER, clonePanelAction.id); - - const SavedObjectFinder = getSavedObjectFinder( - contentManagement.client, - core.uiSettings, - savedObjectsTaggingOss?.getTaggingApi() - ); - const changeViewAction = new ReplacePanelAction(SavedObjectFinder as ReplacePanelSOFinder); - uiActions.registerAction(changeViewAction); - uiActions.attachAction(CONTEXT_MENU_TRIGGER, changeViewAction.id); - const expandPanelAction = new ExpandPanelAction(); uiActions.registerAction(expandPanelAction); uiActions.attachAction(CONTEXT_MENU_TRIGGER, expandPanelAction.id); diff --git a/src/plugins/dashboard/public/dashboard_actions/open_replace_panel_flyout.tsx b/src/plugins/dashboard/public/dashboard_actions/open_replace_panel_flyout.tsx deleted file mode 100644 index befafab7c6a2c..0000000000000 --- a/src/plugins/dashboard/public/dashboard_actions/open_replace_panel_flyout.tsx +++ /dev/null @@ -1,61 +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 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. - */ - -import React from 'react'; - -import { toMountPoint } from '@kbn/kibana-react-plugin/public'; - -import { tracksOverlays } from '@kbn/presentation-containers'; -import { pluginServices } from '../services/plugin_services'; -import { ReplacePanelActionApi } from './replace_panel_action'; -import { ReplacePanelFlyout } from './replace_panel_flyout'; -import { ReplacePanelSOFinder } from '.'; - -export const openReplacePanelFlyout = async ({ - savedObjectFinder, - api, -}: { - savedObjectFinder: ReplacePanelSOFinder; - api: ReplacePanelActionApi; -}) => { - const { - settings: { - theme: { theme$ }, - }, - overlays: { openFlyout }, - } = pluginServices.getServices(); - - // send the overlay ref to the parent if it is capable of tracking overlays - const overlayTracker = tracksOverlays(api.parentApi) ? api.parentApi : undefined; - - const flyoutSession = openFlyout( - toMountPoint( - { - if (flyoutSession) { - if (overlayTracker) overlayTracker.clearOverlays(); - flyoutSession.close(); - } - }} - savedObjectsFinder={savedObjectFinder} - />, - { theme$ } - ), - { - 'data-test-subj': 'dashboardReplacePanel', - ownFocus: true, - onClose: (overlayRef) => { - if (overlayTracker) overlayTracker.clearOverlays(); - overlayRef.close(); - }, - } - ); - - overlayTracker?.openOverlay(flyoutSession); -}; diff --git a/src/plugins/dashboard/public/dashboard_actions/replace_panel_action.test.tsx b/src/plugins/dashboard/public/dashboard_actions/replace_panel_action.test.tsx deleted file mode 100644 index 0e8a4ea4e9fbd..0000000000000 --- a/src/plugins/dashboard/public/dashboard_actions/replace_panel_action.test.tsx +++ /dev/null @@ -1,57 +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 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. - */ - -import { PublishesViewMode, ViewMode } from '@kbn/presentation-publishing'; -import { getMockPresentationContainer } from '@kbn/presentation-containers/mocks'; -import { BehaviorSubject } from 'rxjs'; -import { ReplacePanelSOFinder } from '.'; -import { ReplacePanelAction, ReplacePanelActionApi } from './replace_panel_action'; - -const mockOpenReplacePanelFlyout = jest.fn(); -jest.mock('./open_replace_panel_flyout', () => ({ - openReplacePanelFlyout: () => mockOpenReplacePanelFlyout(), -})); - -describe('replace panel action', () => { - let action: ReplacePanelAction; - let context: { embeddable: ReplacePanelActionApi }; - - const savedObjectFinder = {} as unknown as ReplacePanelSOFinder; - - beforeEach(() => { - action = new ReplacePanelAction(savedObjectFinder); - context = { - embeddable: { - uuid: 'superId', - viewMode: new BehaviorSubject('edit'), - parentApi: getMockPresentationContainer(), - }, - }; - }); - - it('is compatible when api meets all conditions', async () => { - expect(await action.isCompatible(context)).toBe(true); - }); - - it('is incompatible when context lacks necessary functions', async () => { - const emptyContext = { - embeddable: {}, - }; - expect(await action.isCompatible(emptyContext)).toBe(false); - }); - - it('is incompatible when view mode is view', async () => { - (context.embeddable as PublishesViewMode).viewMode = new BehaviorSubject('view'); - expect(await action.isCompatible(context)).toBe(false); - }); - - it('calls open replace panel flyout on execute', async () => { - action.execute(context); - expect(mockOpenReplacePanelFlyout).toHaveBeenCalled(); - }); -}); diff --git a/src/plugins/dashboard/public/dashboard_actions/replace_panel_action.tsx b/src/plugins/dashboard/public/dashboard_actions/replace_panel_action.tsx deleted file mode 100644 index 1830c9b5d53a2..0000000000000 --- a/src/plugins/dashboard/public/dashboard_actions/replace_panel_action.tsx +++ /dev/null @@ -1,75 +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 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. - */ - -import { - apiIsPresentationContainer, - PresentationContainer, - TracksOverlays, -} from '@kbn/presentation-containers'; -import { - apiHasUniqueId, - EmbeddableApiContext, - HasUniqueId, - PublishesPanelTitle, - apiCanAccessViewMode, - CanAccessViewMode, - HasParentApi, - apiHasParentApi, - getInheritedViewMode, -} from '@kbn/presentation-publishing'; -import { Action, IncompatibleActionError } from '@kbn/ui-actions-plugin/public'; -import { ReplacePanelSOFinder } from '.'; -import { openReplacePanelFlyout } from './open_replace_panel_flyout'; -import { dashboardReplacePanelActionStrings } from './_dashboard_actions_strings'; - -export const ACTION_REPLACE_PANEL = 'replacePanel'; - -export type ReplacePanelActionApi = CanAccessViewMode & - HasUniqueId & - Partial & - HasParentApi>; - -const isApiCompatible = (api: unknown | null): api is ReplacePanelActionApi => - Boolean( - apiHasUniqueId(api) && - apiCanAccessViewMode(api) && - apiHasParentApi(api) && - apiIsPresentationContainer(api.parentApi) - ); - -export class ReplacePanelAction implements Action { - public readonly type = ACTION_REPLACE_PANEL; - public readonly id = ACTION_REPLACE_PANEL; - public order = 3; - - constructor(private savedObjectFinder: ReplacePanelSOFinder) {} - - public getDisplayName({ embeddable }: EmbeddableApiContext) { - if (!isApiCompatible(embeddable)) throw new IncompatibleActionError(); - return dashboardReplacePanelActionStrings.getDisplayName(); - } - - public getIconType({ embeddable }: EmbeddableApiContext) { - if (!isApiCompatible(embeddable)) throw new IncompatibleActionError(); - return 'kqlOperand'; - } - - public async isCompatible({ embeddable }: EmbeddableApiContext) { - if (!isApiCompatible(embeddable)) return false; - return getInheritedViewMode(embeddable) === 'edit'; - } - - public async execute({ embeddable }: EmbeddableApiContext) { - if (!isApiCompatible(embeddable)) throw new IncompatibleActionError(); - - openReplacePanelFlyout({ - api: embeddable, - savedObjectFinder: this.savedObjectFinder, - }); - } -} diff --git a/src/plugins/dashboard/public/dashboard_actions/replace_panel_flyout.tsx b/src/plugins/dashboard/public/dashboard_actions/replace_panel_flyout.tsx deleted file mode 100644 index 6d3de4c1e4c71..0000000000000 --- a/src/plugins/dashboard/public/dashboard_actions/replace_panel_flyout.tsx +++ /dev/null @@ -1,95 +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 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. - */ - -import { EuiFlyoutBody, EuiFlyoutHeader, EuiTitle } from '@elastic/eui'; -import React from 'react'; - -import { Toast } from '@kbn/core/public'; -import { getPanelTitle } from '@kbn/presentation-publishing'; -import { pluginServices } from '../services/plugin_services'; -import { ReplacePanelActionApi } from './replace_panel_action'; -import { dashboardReplacePanelActionStrings } from './_dashboard_actions_strings'; -import { ReplacePanelSOFinder } from '.'; - -interface Props { - api: ReplacePanelActionApi; - savedObjectsFinder: ReplacePanelSOFinder; - onClose: () => void; -} - -export class ReplacePanelFlyout extends React.Component { - private lastToast: Toast = { - id: 'panelReplaceToast', - }; - - constructor(props: Props) { - super(props); - } - - public showToast = (name: string) => { - const { - notifications: { toasts }, - } = pluginServices.getServices(); - - // To avoid the clutter of having toast messages cover flyout - // close previous toast message before creating a new one - if (this.lastToast) { - toasts.remove(this.lastToast); - } - - this.lastToast = toasts.addSuccess({ - title: dashboardReplacePanelActionStrings.getSuccessMessage(name), - 'data-test-subj': 'addObjectToContainerSuccess', - }); - }; - - public onReplacePanel = async (savedObjectId: string, type: string, name: string) => { - this.props.api.parentApi.replacePanel(this.props.api.uuid, { - panelType: type, - initialState: { savedObjectId }, - }); - this.showToast(name); - this.props.onClose(); - }; - - public render() { - const { - embeddable: { getEmbeddableFactories }, - } = pluginServices.getServices(); - - const SavedObjectFinder = this.props.savedObjectsFinder; - const savedObjectsFinder = ( - - Boolean(embeddableFactory.savedObjectMetaData) && !embeddableFactory.isContainerType - ) - .map(({ savedObjectMetaData }) => savedObjectMetaData as any)} - showFilter={true} - onChoose={this.onReplacePanel} - /> - ); - - return ( - <> - - -

- - {dashboardReplacePanelActionStrings.getFlyoutHeader(getPanelTitle(this.props.api))} - -

-
-
- {savedObjectsFinder} - - ); - } -} diff --git a/src/plugins/dashboard/public/dashboard_app/_dashboard_app_strings.ts b/src/plugins/dashboard/public/dashboard_app/_dashboard_app_strings.ts index 1d53561b619d9..a513d725f1f31 100644 --- a/src/plugins/dashboard/public/dashboard_app/_dashboard_app_strings.ts +++ b/src/plugins/dashboard/public/dashboard_app/_dashboard_app_strings.ts @@ -99,13 +99,17 @@ export const getNewDashboardTitle = () => defaultMessage: 'New Dashboard', }); -export const getPanelAddedSuccessString = (savedObjectName: string) => - i18n.translate('dashboard.addPanel.newEmbeddableAddedSuccessMessageTitle', { - defaultMessage: '{savedObjectName} was added', - values: { - savedObjectName, - }, - }); +export const getPanelAddedSuccessString = (savedObjectName?: string) => + savedObjectName + ? i18n.translate('dashboard.addPanel.newEmbeddableAddedSuccessMessageTitle', { + defaultMessage: '{savedObjectName} was added', + values: { + savedObjectName, + }, + }) + : i18n.translate('dashboard.addPanel.newEmbeddableWithNoTitleAddedSuccessMessageTitle', { + defaultMessage: 'A panel was added', + }); export const getPanelTooOldErrorString = () => i18n.translate('dashboard.loadURLError.PanelTooOld', { diff --git a/src/plugins/dashboard/public/dashboard_container/embeddable/dashboard_container.tsx b/src/plugins/dashboard/public/dashboard_container/embeddable/dashboard_container.tsx index 915954a4321b6..42e4e162e0795 100644 --- a/src/plugins/dashboard/public/dashboard_container/embeddable/dashboard_container.tsx +++ b/src/plugins/dashboard/public/dashboard_container/embeddable/dashboard_container.tsx @@ -45,7 +45,6 @@ import { v4 } from 'uuid'; import { DashboardLocatorParams, DASHBOARD_CONTAINER_TYPE } from '../..'; import { DashboardContainerInput, DashboardPanelState } from '../../../common'; import { getReferencesForPanelId } from '../../../common/dashboard_container/persistable_state/dashboard_container_references'; -import { dashboardReplacePanelActionStrings } from '../../dashboard_actions/_dashboard_actions_strings'; import { DASHBOARD_APP_ID, DASHBOARD_LOADED_EVENT, @@ -83,6 +82,7 @@ import { dashboardTypeDisplayLowercase, dashboardTypeDisplayName, } from './dashboard_container_factory'; +import { getPanelAddedSuccessString } from '../../dashboard_app/_dashboard_app_strings'; export interface InheritedChildInput { filters: Filter[]; @@ -425,7 +425,7 @@ export class DashboardContainer const onSuccess = (id?: string, title?: string) => { if (!displaySuccessMessage) return; toasts.addSuccess({ - title: dashboardReplacePanelActionStrings.getSuccessMessage(title), + title: getPanelAddedSuccessString(title), 'data-test-subj': 'addEmbeddableToDashboardSuccess', }); this.setScrollToPanelId(id); diff --git a/src/plugins/dashboard/tsconfig.json b/src/plugins/dashboard/tsconfig.json index b484a9f6c51c3..2f4b399a727ef 100644 --- a/src/plugins/dashboard/tsconfig.json +++ b/src/plugins/dashboard/tsconfig.json @@ -53,7 +53,6 @@ "@kbn/core-execution-context-common", "@kbn/core-custom-branding-browser", "@kbn/shared-ux-router", - "@kbn/saved-objects-finder-plugin", "@kbn/saved-objects-management-plugin", "@kbn/shared-ux-button-toolbar", "@kbn/core-saved-objects-server", diff --git a/src/plugins/presentation_panel/public/panel_actions/customize_panel_action/customize_panel_action.tsx b/src/plugins/presentation_panel/public/panel_actions/customize_panel_action/customize_panel_action.tsx index fd5810755dd83..f5ab9c58b8a9f 100644 --- a/src/plugins/presentation_panel/public/panel_actions/customize_panel_action/customize_panel_action.tsx +++ b/src/plugins/presentation_panel/public/panel_actions/customize_panel_action/customize_panel_action.tsx @@ -45,13 +45,13 @@ export const isApiCompatibleWithCustomizePanelAction = ( export class CustomizePanelAction implements Action { public type = ACTION_CUSTOMIZE_PANEL; public id = ACTION_CUSTOMIZE_PANEL; - public order = 40; + public order = 45; constructor() {} public getDisplayName({ embeddable }: EmbeddableApiContext): string { return i18n.translate('presentationPanel.action.customizePanel.displayName', { - defaultMessage: 'Panel settings', + defaultMessage: 'Settings', }); } diff --git a/src/plugins/presentation_panel/public/panel_actions/customize_panel_action/customize_panel_editor.tsx b/src/plugins/presentation_panel/public/panel_actions/customize_panel_action/customize_panel_editor.tsx index cafb522c0af8d..d74b55a69dae4 100644 --- a/src/plugins/presentation_panel/public/panel_actions/customize_panel_action/customize_panel_editor.tsx +++ b/src/plugins/presentation_panel/public/panel_actions/customize_panel_action/customize_panel_editor.tsx @@ -290,7 +290,7 @@ export const CustomizePanelEditor = ({

diff --git a/src/plugins/presentation_panel/public/panel_actions/remove_panel_action/remove_panel_action.ts b/src/plugins/presentation_panel/public/panel_actions/remove_panel_action/remove_panel_action.ts index 8080a7c307957..ec1cc7d442e0f 100644 --- a/src/plugins/presentation_panel/public/panel_actions/remove_panel_action/remove_panel_action.ts +++ b/src/plugins/presentation_panel/public/panel_actions/remove_panel_action/remove_panel_action.ts @@ -34,11 +34,18 @@ export class RemovePanelAction implements Action { public readonly id = ACTION_REMOVE_PANEL; public order = 1; + public grouping = [ + { + id: 'delete_panel_action', + order: 1, + }, + ]; + constructor() {} public getDisplayName() { return i18n.translate('presentationPanel.action.removePanel.displayName', { - defaultMessage: 'Delete from dashboard', + defaultMessage: 'Remove', }); } diff --git a/src/plugins/presentation_panel/public/panel_component/_presentation_panel.scss b/src/plugins/presentation_panel/public/panel_component/_presentation_panel.scss index 74767afa5bba0..3574a829ba852 100644 --- a/src/plugins/presentation_panel/public/panel_component/_presentation_panel.scss +++ b/src/plugins/presentation_panel/public/panel_component/_presentation_panel.scss @@ -148,16 +148,6 @@ .embPanel--editing { transition: all $euiAnimSpeedFast $euiAnimSlightResistance; - outline-width: $euiBorderWidthThin; - - &:hover, - &:focus { - @include euiSlightShadowHover; - - .embPanel__emptyTitleDragHandle { - display: block; - } - } .embPanel--dragHandle { transition: background-color $euiAnimSpeedFast $euiAnimSlightResistance; diff --git a/src/plugins/presentation_panel/public/panel_component/panel_header/presentation_panel_context_menu.tsx b/src/plugins/presentation_panel/public/panel_component/panel_header/presentation_panel_context_menu.tsx index ff9f7766baadf..6c5aebf3154b7 100644 --- a/src/plugins/presentation_panel/public/panel_component/panel_header/presentation_panel_context_menu.tsx +++ b/src/plugins/presentation_panel/public/panel_component/panel_header/presentation_panel_context_menu.tsx @@ -84,14 +84,15 @@ export const PresentationPanelContextMenu = ({ (action) => disabledActions.indexOf(action.id) === -1 ); } - compatibleActions.sort( - ({ order: orderA }, { order: orderB }) => (orderB || 0) - (orderA || 0) - ); if (actionPredicate) { compatibleActions = compatibleActions.filter(({ id }) => actionPredicate(id)); } + compatibleActions.sort( + ({ order: orderA }, { order: orderB }) => (orderB || 0) - (orderA || 0) + ); + /** * Build context menu panel from actions */ diff --git a/src/plugins/ui_actions/public/context_menu/build_eui_context_menu_panels.test.ts b/src/plugins/ui_actions/public/context_menu/build_eui_context_menu_panels.test.ts index 7a6cb3a4c5265..8982c91dff961 100644 --- a/src/plugins/ui_actions/public/context_menu/build_eui_context_menu_panels.test.ts +++ b/src/plugins/ui_actions/public/context_menu/build_eui_context_menu_panels.test.ts @@ -13,13 +13,13 @@ import { PresentableGrouping } from '@kbn/ui-actions-browser'; const createTestAction = ({ type, - dispayName, + displayName, order, grouping = undefined, disabled, }: { type?: string; - dispayName: string; + displayName: string; order?: number; grouping?: PresentableGrouping; disabled?: boolean; @@ -27,7 +27,7 @@ const createTestAction = ({ createAction({ id: type as string, type, - getDisplayName: () => dispayName, + getDisplayName: () => displayName, order, execute: async () => {}, grouping, @@ -47,27 +47,27 @@ test('sorts items in DESC order by "order" field first, then by display name', a createTestAction({ order: 1, type: 'foo', - dispayName: 'a-1', + displayName: 'a-1', }), createTestAction({ order: 2, type: 'foo', - dispayName: 'a-2', + displayName: 'a-2', }), createTestAction({ order: 3, type: 'foo', - dispayName: 'a-3', + displayName: 'a-3', }), createTestAction({ order: 2, type: 'foo', - dispayName: 'b-2', + displayName: 'b-2', }), createTestAction({ order: 2, type: 'foo', - dispayName: 'c-2', + displayName: 'c-2', }), ].sort(() => 0.5 - Math.random()); @@ -133,7 +133,7 @@ test('can build menu with one action', async () => { actions: [ { action: createTestAction({ - dispayName: 'Foo', + displayName: 'Foo', }), context: {}, trigger: { @@ -162,11 +162,11 @@ test('orders items according to "order" field', async () => { const actions = [ createTestAction({ order: 1, - dispayName: 'Foo', + displayName: 'Foo', }), createTestAction({ order: 2, - dispayName: 'Bar', + displayName: 'Bar', }), ]; const menu = await buildContextMenuForActions({ @@ -179,11 +179,11 @@ test('orders items according to "order" field', async () => { const actions2 = [ createTestAction({ order: 2, - dispayName: 'Bar', + displayName: 'Bar', }), createTestAction({ order: 1, - dispayName: 'Foo', + displayName: 'Foo', }), ]; const menu2 = await buildContextMenuForActions({ @@ -197,19 +197,19 @@ test('orders items according to "order" field', async () => { test('hides items behind in "More" submenu if there are more than 4 actions', async () => { const actions = [ createTestAction({ - dispayName: 'Foo 1', + displayName: 'Foo 1', }), createTestAction({ - dispayName: 'Foo 2', + displayName: 'Foo 2', }), createTestAction({ - dispayName: 'Foo 3', + displayName: 'Foo 3', }), createTestAction({ - dispayName: 'Foo 4', + displayName: 'Foo 4', }), createTestAction({ - dispayName: 'Foo 5', + displayName: 'Foo 5', }), ]; const menu = await buildContextMenuForActions({ @@ -257,16 +257,16 @@ test('hides items behind in "More" submenu if there are more than 4 actions', as test('separates grouped items from main items with a separator', async () => { const actions = [ createTestAction({ - dispayName: 'Foo 1', + displayName: 'Foo 1', }), createTestAction({ - dispayName: 'Foo 2', + displayName: 'Foo 2', }), createTestAction({ - dispayName: 'Foo 3', + displayName: 'Foo 3', }), createTestAction({ - dispayName: 'Foo 4', + displayName: 'Foo 4', grouping: [ { id: 'testGroup', @@ -319,16 +319,16 @@ test('separates grouped items from main items with a separator', async () => { test('separates multiple groups each with its own separator', async () => { const actions = [ createTestAction({ - dispayName: 'Foo 1', + displayName: 'Foo 1', }), createTestAction({ - dispayName: 'Foo 2', + displayName: 'Foo 2', }), createTestAction({ - dispayName: 'Foo 3', + displayName: 'Foo 3', }), createTestAction({ - dispayName: 'Foo 4', + displayName: 'Foo 4', grouping: [ { id: 'testGroup', @@ -337,7 +337,7 @@ test('separates multiple groups each with its own separator', async () => { ], }), createTestAction({ - dispayName: 'Foo 5', + displayName: 'Foo 5', grouping: [ { id: 'testGroup2', @@ -405,7 +405,7 @@ test('separates multiple groups each with its own separator', async () => { test('does not add separator for first grouping if there are no main items', async () => { const actions = [ createTestAction({ - dispayName: 'Foo 4', + displayName: 'Foo 4', grouping: [ { id: 'testGroup', @@ -414,7 +414,7 @@ test('does not add separator for first grouping if there are no main items', asy ], }), createTestAction({ - dispayName: 'Foo 5', + displayName: 'Foo 5', grouping: [ { id: 'testGroup2', @@ -467,11 +467,11 @@ test('does not add separator for first grouping if there are no main items', asy test('it creates disabled actions', async () => { const actions = [ createTestAction({ - dispayName: 'Foo 4', + displayName: 'Foo 4', disabled: true, }), createTestAction({ - dispayName: 'Foo 5', + displayName: 'Foo 5', }), ]; const menu = await buildContextMenuForActions({ diff --git a/src/plugins/ui_actions/public/context_menu/build_eui_context_menu_panels.tsx b/src/plugins/ui_actions/public/context_menu/build_eui_context_menu_panels.tsx index 4059f954001ec..943077ae8e554 100644 --- a/src/plugins/ui_actions/public/context_menu/build_eui_context_menu_panels.tsx +++ b/src/plugins/ui_actions/public/context_menu/build_eui_context_menu_panels.tsx @@ -8,7 +8,6 @@ import * as React from 'react'; import { EuiContextMenuPanelDescriptor, EuiContextMenuPanelItemDescriptor } from '@elastic/eui'; -import _ from 'lodash'; import { i18n } from '@kbn/i18n'; import type { Trigger } from '@kbn/ui-actions-browser/src/triggers'; import type { Action, ActionExecutionContext, ActionInternal } from '../actions'; @@ -179,10 +178,12 @@ export async function buildContextMenuForActions({ for (const panel of Object.values(panels)) { const items = panel.items.filter(Boolean) as ItemDescriptor[]; - panel.items = _.sortBy( - items, - (a) => -1 * (a._order ?? 0), - (a) => a._title + panel.items = items.sort( + ({ _order: orderA, _title: titleA }, { _order: orderB, _title: titleB }) => { + const orderComparison = (orderB || 0) - (orderA || 0); + if (orderComparison !== 0) return orderComparison; + return (titleA || '').localeCompare(titleB || ''); + } ); } diff --git a/test/functional/apps/dashboard/group3/index.ts b/test/functional/apps/dashboard/group3/index.ts index efa86ffee010f..035ac538ee99a 100644 --- a/test/functional/apps/dashboard/group3/index.ts +++ b/test/functional/apps/dashboard/group3/index.ts @@ -33,7 +33,6 @@ export default function ({ getService, loadTestFile }: FtrProviderContext) { } else { loadTestFile(require.resolve('./dashboard_time_picker')); loadTestFile(require.resolve('./bwc_shared_urls')); - loadTestFile(require.resolve('./panel_replacing')); loadTestFile(require.resolve('./panel_cloning')); loadTestFile(require.resolve('./copy_panel_to')); loadTestFile(require.resolve('./panel_context_menu')); diff --git a/test/functional/apps/dashboard/group3/panel_context_menu.ts b/test/functional/apps/dashboard/group3/panel_context_menu.ts index 4abf860cb17fc..d2807bc006d4c 100644 --- a/test/functional/apps/dashboard/group3/panel_context_menu.ts +++ b/test/functional/apps/dashboard/group3/panel_context_menu.ts @@ -53,7 +53,6 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await dashboardPanelActions.expectExistsEditPanelAction(); await dashboardPanelActions.expectExistsClonePanelAction(); - await dashboardPanelActions.expectExistsReplacePanelAction(); await dashboardPanelActions.expectExistsRemovePanelAction(); await dashboardPanelActions.expectExistsToggleExpandAction(); }); @@ -69,7 +68,6 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await dashboardPanelActions.expectExistsEditPanelAction(); await dashboardPanelActions.expectExistsClonePanelAction(); - await dashboardPanelActions.expectExistsReplacePanelAction(); await dashboardPanelActions.expectExistsRemovePanelAction(); // Get rid of the timestamp in the url. @@ -156,7 +154,6 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { it('context menu actions are hidden in view mode', async function () { await dashboardPanelActions.expectMissingEditPanelAction(); await dashboardPanelActions.expectMissingDuplicatePanelAction(); - await dashboardPanelActions.expectMissingReplacePanelAction(); await dashboardPanelActions.expectMissingRemovePanelAction(); }); @@ -168,7 +165,6 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { it('some context menu actions should be present', async function () { await dashboardPanelActions.expectExistsEditPanelAction(); await dashboardPanelActions.expectExistsClonePanelAction(); - await dashboardPanelActions.expectExistsReplacePanelAction(); }); it('"remove panel" action should not be present', async function () { diff --git a/test/functional/apps/dashboard/group3/panel_replacing.ts b/test/functional/apps/dashboard/group3/panel_replacing.ts deleted file mode 100644 index 1cb344748594f..0000000000000 --- a/test/functional/apps/dashboard/group3/panel_replacing.ts +++ /dev/null @@ -1,91 +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 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. - */ - -import expect from '@kbn/expect'; -import { - PIE_CHART_VIS_NAME, - AREA_CHART_VIS_NAME, - LINE_CHART_VIS_NAME, -} from '../../../page_objects/dashboard_page'; -import { FtrProviderContext } from '../../../ftr_provider_context'; - -export default function ({ getService, getPageObjects }: FtrProviderContext) { - const browser = getService('browser'); - const dashboardPanelActions = getService('dashboardPanelActions'); - const dashboardAddPanel = getService('dashboardAddPanel'); - const dashboardReplacePanel = getService('dashboardReplacePanel'); - const dashboardVisualizations = getService('dashboardVisualizations'); - const PageObjects = getPageObjects([ - 'dashboard', - 'header', - 'visualize', - 'discover', - 'timePicker', - ]); - - describe('replace dashboard panels', function viewEditModeTests() { - let intialDimensions: undefined | Array<{ width: number; height: number }>; - - before(async function () { - await PageObjects.dashboard.initTests(); - await PageObjects.dashboard.preserveCrossAppState(); - await PageObjects.dashboard.clickNewDashboard(); - await PageObjects.timePicker.setHistoricalDataRange(); - await dashboardAddPanel.addVisualization(PIE_CHART_VIS_NAME); - await dashboardAddPanel.addVisualization(LINE_CHART_VIS_NAME); - intialDimensions = await PageObjects.dashboard.getPanelDimensions(); - }); - - after(async function () { - await PageObjects.dashboard.gotoDashboardLandingPage(); - }); - - it('replaces old panel with selected panel', async () => { - await dashboardPanelActions.replacePanelByTitle(PIE_CHART_VIS_NAME); - await dashboardReplacePanel.replaceEmbeddable(AREA_CHART_VIS_NAME); - await PageObjects.header.waitUntilLoadingHasFinished(); - const panelTitles = await PageObjects.dashboard.getPanelTitles(); - expect(panelTitles.length).to.be(2); - expect(panelTitles[0]).to.be(AREA_CHART_VIS_NAME); - const newDimensions = await PageObjects.dashboard.getPanelDimensions(); - expect(intialDimensions![0]).to.eql(newDimensions[0]); - }); - - it('replaced panel persisted correctly when dashboard is hard refreshed', async () => { - const currentUrl = await browser.getCurrentUrl(); - await browser.get(currentUrl, true); - const alert = await browser.getAlert(); - await alert?.accept(); - await PageObjects.header.waitUntilLoadingHasFinished(); - await PageObjects.dashboard.waitForRenderComplete(); - const panelTitles = await PageObjects.dashboard.getPanelTitles(); - expect(panelTitles.length).to.be(2); - expect(panelTitles[0]).to.be(AREA_CHART_VIS_NAME); - }); - - it('replaced panel with saved search', async () => { - const replacedSearch = 'replaced saved search'; - await dashboardVisualizations.createSavedSearch({ - name: replacedSearch, - fields: ['bytes', 'agent'], - }); - await PageObjects.header.clickDashboard(); - const inViewMode = await PageObjects.dashboard.getIsInViewMode(); - if (inViewMode) { - await PageObjects.dashboard.switchToEditMode(); - } - await dashboardPanelActions.replacePanelByTitle(AREA_CHART_VIS_NAME); - await dashboardReplacePanel.replaceEmbeddable(replacedSearch, 'Saved search'); - await PageObjects.header.waitUntilLoadingHasFinished(); - await PageObjects.dashboard.waitForRenderComplete(); - const panelTitles = await PageObjects.dashboard.getPanelTitles(); - expect(panelTitles.length).to.be(2); - expect(panelTitles[0]).to.be(replacedSearch); - }); - }); -} diff --git a/test/functional/apps/dashboard_elements/image_embeddable/image_embeddable.ts b/test/functional/apps/dashboard_elements/image_embeddable/image_embeddable.ts index 6fc586fb35bba..0772c01def58d 100644 --- a/test/functional/apps/dashboard_elements/image_embeddable/image_embeddable.ts +++ b/test/functional/apps/dashboard_elements/image_embeddable/image_embeddable.ts @@ -54,6 +54,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { it('image embeddable should support drilldowns', async () => { await dashboardPanelActions.openContextMenu(); + await dashboardPanelActions.clickContextMenuMoreItem(); await dashboardDrilldownPanelActions.expectExistsCreateDrilldownAction(); await dashboardDrilldownPanelActions.clickCreateDrilldown(); await dashboardDrilldownsManage.expectsCreateDrilldownFlyoutOpen(); diff --git a/test/functional/apps/discover/embeddable/_saved_search_embeddable.ts b/test/functional/apps/discover/embeddable/_saved_search_embeddable.ts index 052e33f29f4e8..f86358e584766 100644 --- a/test/functional/apps/discover/embeddable/_saved_search_embeddable.ts +++ b/test/functional/apps/discover/embeddable/_saved_search_embeddable.ts @@ -12,8 +12,6 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { const browser = getService('browser'); const dataGrid = getService('dataGrid'); const dashboardAddPanel = getService('dashboardAddPanel'); - const dashboardPanelActions = getService('dashboardPanelActions'); - const dashboardReplacePanel = getService('dashboardReplacePanel'); const filterBar = getService('filterBar'); const queryBar = getService('queryBar'); const esArchiver = getService('esArchiver'); @@ -129,18 +127,6 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { ); }); - it('should replace a panel with a saved search', async () => { - await dashboardAddPanel.addVisualization('Rendering Test: datatable'); - await PageObjects.header.waitUntilLoadingHasFinished(); - await PageObjects.dashboard.waitForRenderComplete(); - await dashboardPanelActions.replacePanelByTitle('Rendering Test: datatable'); - await dashboardReplacePanel.replaceEmbeddable('Rendering-Test:-saved-search'); - await PageObjects.header.waitUntilLoadingHasFinished(); - await PageObjects.dashboard.waitForRenderComplete(); - await testSubjects.missingOrFail('embeddableError'); - expect(await PageObjects.discover.getSavedSearchDocumentCount()).to.be('4,633 documents'); - }); - it('should not show the full screen button', async () => { await addSearchEmbeddableToDashboard(); await testSubjects.missingOrFail('dataGridFullScreenButton'); diff --git a/test/functional/services/dashboard/panel_actions.ts b/test/functional/services/dashboard/panel_actions.ts index b322a553778c8..49a6f0ee1ceba 100644 --- a/test/functional/services/dashboard/panel_actions.ts +++ b/test/functional/services/dashboard/panel_actions.ts @@ -210,6 +210,8 @@ export class DashboardPanelActionsService extends FtrService { } else { await this.openContextMenu(); } + const isActionVisible = await this.testSubjects.exists(CLONE_PANEL_DATA_TEST_SUBJ); + if (!isActionVisible) await this.clickContextMenuMoreItem(); await this.testSubjects.click(CLONE_PANEL_DATA_TEST_SUBJ); await this.dashboard.waitForRenderComplete(); } @@ -352,11 +354,6 @@ export class DashboardPanelActionsService extends FtrService { await this.expectExistsPanelAction(testSubj, title); } - async expectExistsReplacePanelAction() { - this.log.debug('expectExistsReplacePanelAction'); - await this.expectExistsPanelAction(REPLACE_PANEL_DATA_TEST_SUBJ); - } - async expectExistsClonePanelAction() { this.log.debug('expectExistsClonePanelAction'); await this.expectExistsPanelAction(CLONE_PANEL_DATA_TEST_SUBJ); @@ -383,11 +380,6 @@ export class DashboardPanelActionsService extends FtrService { await this.expectMissingPanelAction(EDIT_PANEL_DATA_TEST_SUBJ); } - async expectMissingReplacePanelAction() { - this.log.debug('expectMissingReplacePanelAction'); - await this.expectMissingPanelAction(REPLACE_PANEL_DATA_TEST_SUBJ); - } - async expectMissingDuplicatePanelAction() { this.log.debug('expectMissingDuplicatePanelAction'); await this.expectMissingPanelAction(CLONE_PANEL_DATA_TEST_SUBJ); diff --git a/test/functional/services/dashboard/panel_drilldown_actions.ts b/test/functional/services/dashboard/panel_drilldown_actions.ts index 3a240d58c983d..5b76ce62dd02d 100644 --- a/test/functional/services/dashboard/panel_drilldown_actions.ts +++ b/test/functional/services/dashboard/panel_drilldown_actions.ts @@ -22,7 +22,7 @@ export function DashboardDrilldownPanelActionsProvider({ getService }: FtrProvid await testSubjects.existOrFail(CREATE_DRILLDOWN_DATA_TEST_SUBJ); } - async expectMissingCreateDrilldwonAction() { + async expectMissingCreateDrilldownAction() { log.debug('expectMissingCreateDrilldownAction'); await testSubjects.existOrFail(MANAGE_DRILLDOWNS_DATA_TEST_SUBJ); } diff --git a/x-pack/plugins/cases/public/components/visualizations/actions/add_to_existing_case.test.tsx b/x-pack/plugins/cases/public/components/visualizations/actions/add_to_existing_case.test.tsx index a32ece05eac74..6742242b71fb2 100644 --- a/x-pack/plugins/cases/public/components/visualizations/actions/add_to_existing_case.test.tsx +++ b/x-pack/plugins/cases/public/components/visualizations/actions/add_to_existing_case.test.tsx @@ -110,7 +110,7 @@ describe('createAddToExistingCaseLensAction', () => { }); test('it should return display name', () => { - expect(action.getDisplayName(context)).toEqual('Add to existing case'); + expect(action.getDisplayName(context)).toEqual('Add to case'); }); it('should return icon type', () => { diff --git a/x-pack/plugins/cases/public/components/visualizations/actions/add_to_new_case.test.tsx b/x-pack/plugins/cases/public/components/visualizations/actions/add_to_new_case.test.tsx deleted file mode 100644 index 3549ca3301d18..0000000000000 --- a/x-pack/plugins/cases/public/components/visualizations/actions/add_to_new_case.test.tsx +++ /dev/null @@ -1,207 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { LENS_EMBEDDABLE_TYPE, type Embeddable as LensEmbeddable } from '@kbn/lens-plugin/public'; -import { ErrorEmbeddable } from '@kbn/embeddable-plugin/public'; -import type { Action } from '@kbn/ui-actions-plugin/public'; -import { waitFor } from '@testing-library/react'; - -import { createAddToNewCaseLensAction } from './add_to_new_case'; -import type { ActionContext } from './types'; -import { useCasesAddToNewCaseFlyout } from '../../create/flyout/use_cases_add_to_new_case_flyout'; -import React from 'react'; -import { toMountPoint } from '@kbn/kibana-react-plugin/public'; -import { - getMockApplications$, - getMockCaseUiActionProps, - getMockCurrentAppId$, - mockAttributes, - MockEmbeddable, - mockTimeRange, -} from './mocks'; -import ReactDOM, { unmountComponentAtNode } from 'react-dom'; -import { useKibana } from '../../../common/lib/kibana'; -import { canUseCases } from '../../../client/helpers/can_use_cases'; -import { getCaseOwnerByAppId } from '../../../../common/utils/owner'; - -const element = document.createElement('div'); -document.body.appendChild(element); - -jest.mock('@kbn/kibana-react-plugin/public', () => ({ - toMountPoint: jest.fn(), -})); - -jest.mock('../../../common/lib/kibana', () => { - return { - useKibana: jest.fn(), - KibanaContextProvider: jest - .fn() - .mockImplementation(({ children, ...props }) =>
{children}
), - }; -}); - -jest.mock('../../create/flyout/use_cases_add_to_new_case_flyout', () => ({ - useCasesAddToNewCaseFlyout: jest.fn(), -})); - -jest.mock('../../../client/helpers/can_use_cases', () => { - const actual = jest.requireActual('../../../client/helpers/can_use_cases'); - return { - ...actual, - canUseCases: jest.fn(), - }; -}); - -jest.mock('react-dom', () => { - const original = jest.requireActual('react-dom'); - return { ...original, unmountComponentAtNode: jest.fn() }; -}); - -jest.mock('./action_wrapper'); - -jest.mock('../../../../common/utils/owner', () => ({ - getCaseOwnerByAppId: jest.fn().mockReturnValue('securitySolution'), -})); - -describe('createAddToNewCaseLensAction', () => { - const mockEmbeddable = new MockEmbeddable(LENS_EMBEDDABLE_TYPE, { - id: 'mockId', - attributes: mockAttributes, - timeRange: mockTimeRange, - }) as unknown as LensEmbeddable; - - const context = { - embeddable: mockEmbeddable, - } as unknown as ActionContext; - - const caseUiActionProps = getMockCaseUiActionProps(); - - const mockUseCasesAddToNewCaseFlyout = useCasesAddToNewCaseFlyout as jest.Mock; - const mockOpenFlyout = jest.fn(); - const mockMount = jest.fn(); - let action: Action; - const mockCasePermissions = jest.fn(); - - beforeEach(() => { - jest.clearAllMocks(); - mockUseCasesAddToNewCaseFlyout.mockReturnValue({ - open: mockOpenFlyout, - }); - - (useKibana as jest.Mock).mockReturnValue({ - services: { - application: { - currentAppId$: getMockCurrentAppId$(), - applications$: getMockApplications$(), - }, - }, - }); - - (canUseCases as jest.Mock).mockReturnValue( - mockCasePermissions.mockReturnValue({ create: true, update: true }) - ); - - (toMountPoint as jest.Mock).mockImplementation((node) => { - ReactDOM.render(node, element); - return mockMount; - }); - - jest.clearAllMocks(); - action = createAddToNewCaseLensAction(caseUiActionProps); - }); - - test('it should return display name', () => { - expect(action.getDisplayName(context)).toEqual('Add to new case'); - }); - - it('should return icon type', () => { - expect(action.getIconType(context)).toEqual('casesApp'); - }); - - describe('isCompatible', () => { - it('should return false if error embeddable', async () => { - expect( - await action.isCompatible({ - ...context, - embeddable: new ErrorEmbeddable('some error', { - id: '123', - }) as unknown as LensEmbeddable, - }) - ).toEqual(false); - }); - - it('should return false if not lens embeddable', async () => { - expect( - await action.isCompatible({ - ...context, - embeddable: new MockEmbeddable('not_lens') as unknown as LensEmbeddable, - }) - ).toEqual(false); - }); - - it('should return false if no permission', async () => { - mockCasePermissions.mockReturnValue({ create: false, update: false }); - expect(await action.isCompatible(context)).toEqual(false); - }); - - it('should return true if is lens embeddable', async () => { - expect(await action.isCompatible(context)).toEqual(true); - }); - - it('should check permission with undefined if owner is not found', async () => { - (getCaseOwnerByAppId as jest.Mock).mockReturnValue(undefined); - await action.isCompatible(context); - expect(mockCasePermissions).toBeCalledWith(undefined); - }); - }); - - describe('execute', () => { - beforeEach(async () => { - await action.execute(context); - }); - - it('should execute', () => { - expect(toMountPoint).toHaveBeenCalled(); - expect(mockMount).toHaveBeenCalled(); - }); - }); - - describe('Add to new case flyout', () => { - beforeEach(async () => { - await action.execute(context); - }); - - it('should open flyout', async () => { - await waitFor(() => { - expect(mockOpenFlyout).toHaveBeenCalledWith({ - attachments: [ - { - persistableStateAttachmentState: { - attributes: mockAttributes, - timeRange: mockTimeRange, - }, - persistableStateAttachmentTypeId: '.lens', - type: 'persistableState', - }, - ], - }); - }); - }); - - it('should have correct onClose handler', () => { - const onClose = mockUseCasesAddToNewCaseFlyout.mock.calls[0][0].onClose; - onClose(); - expect(unmountComponentAtNode as jest.Mock).toHaveBeenCalled(); - }); - - it('should have correct onSuccess handler', () => { - const onSuccess = mockUseCasesAddToNewCaseFlyout.mock.calls[0][0].onSuccess; - onSuccess(); - expect(unmountComponentAtNode as jest.Mock).toHaveBeenCalled(); - }); - }); -}); diff --git a/x-pack/plugins/cases/public/components/visualizations/actions/add_to_new_case.tsx b/x-pack/plugins/cases/public/components/visualizations/actions/add_to_new_case.tsx deleted file mode 100644 index 269b38dc4e3b9..0000000000000 --- a/x-pack/plugins/cases/public/components/visualizations/actions/add_to_new_case.tsx +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ -import React, { useEffect, useMemo } from 'react'; -import { unmountComponentAtNode } from 'react-dom'; - -import { createAction } from '@kbn/ui-actions-plugin/public'; -import { isErrorEmbeddable } from '@kbn/embeddable-plugin/public'; - -import { toMountPoint } from '@kbn/kibana-react-plugin/public'; -import type { Embeddable as LensEmbeddable } from '@kbn/lens-plugin/public'; -import { getCaseOwnerByAppId } from '../../../../common/utils/owner'; -import { hasInput, isLensEmbeddable, getLensCaseAttachment } from './utils'; - -import type { ActionContext, CasesUIActionProps } from './types'; -import { ADD_TO_CASE_SUCCESS, ADD_TO_NEW_CASE_DISPLAYNAME } from './translations'; -import { useCasesAddToNewCaseFlyout } from '../../create/flyout/use_cases_add_to_new_case_flyout'; -import { ActionWrapper } from './action_wrapper'; -import { canUseCases } from '../../../client/helpers/can_use_cases'; - -export const ACTION_ID = 'embeddable_addToNewCase'; -export const DEFAULT_DARK_MODE = 'theme:darkMode' as const; - -interface Props { - embeddable: LensEmbeddable; - onSuccess: () => void; - onClose: () => void; -} - -const AddToNewCaseFlyoutWrapper: React.FC = ({ embeddable, onClose, onSuccess }) => { - const { timeRange } = embeddable.getInput(); - const attributes = embeddable.getFullAttributes(); - const createNewCaseFlyout = useCasesAddToNewCaseFlyout({ - onClose, - onSuccess, - toastContent: ADD_TO_CASE_SUCCESS, - }); - - // we've checked attributes exists before rendering (isCompatible), attributes should not be undefined here - const attachments = useMemo( - () => (attributes != null ? [getLensCaseAttachment({ attributes, timeRange })] : []), - [attributes, timeRange] - ); - - useEffect(() => { - createNewCaseFlyout.open({ attachments }); - }, [attachments, createNewCaseFlyout]); - - return null; -}; - -AddToNewCaseFlyoutWrapper.displayName = 'AddToNewCaseFlyoutWrapper'; - -export const createAddToNewCaseLensAction = ({ - core, - plugins, - storage, - history, - caseContextProps, -}: CasesUIActionProps) => { - const { application: applicationService, theme } = core; - - let currentAppId: string | undefined; - - applicationService?.currentAppId$.subscribe((appId) => { - currentAppId = appId; - }); - - return createAction({ - id: ACTION_ID, - type: 'actionButton', - getIconType: () => 'casesApp', - getDisplayName: () => ADD_TO_NEW_CASE_DISPLAYNAME, - isCompatible: async ({ embeddable }) => { - const owner = getCaseOwnerByAppId(currentAppId); - const casePermissions = canUseCases(applicationService.capabilities)( - owner ? [owner] : undefined - ); - - return ( - !isErrorEmbeddable(embeddable) && - isLensEmbeddable(embeddable) && - casePermissions.update && - casePermissions.create && - hasInput(embeddable) - ); - }, - execute: async ({ embeddable }) => { - const targetDomElement = document.createElement('div'); - - const cleanupDom = () => { - if (targetDomElement != null) { - unmountComponentAtNode(targetDomElement); - } - }; - - const onFlyoutClose = () => { - cleanupDom(); - }; - - const mount = toMountPoint( - - - , - { theme$: theme.theme$ } - ); - - mount(targetDomElement); - }, - }); -}; diff --git a/x-pack/plugins/cases/public/components/visualizations/actions/register.ts b/x-pack/plugins/cases/public/components/visualizations/actions/register.ts index f470a0a34fdcd..70d0d6d7a84d4 100644 --- a/x-pack/plugins/cases/public/components/visualizations/actions/register.ts +++ b/x-pack/plugins/cases/public/components/visualizations/actions/register.ts @@ -7,7 +7,6 @@ import { CONTEXT_MENU_TRIGGER } from '@kbn/embeddable-plugin/public'; -import { createAddToNewCaseLensAction } from './add_to_new_case'; import { createAddToExistingCaseLensAction } from './add_to_existing_case'; import type { CasesUIActionProps } from './types'; @@ -28,15 +27,6 @@ const registerLensActions = ({ history, storage, }: CasesUIActionProps) => { - const addToNewCaseAction = createAddToNewCaseLensAction({ - core, - plugins, - caseContextProps, - history, - storage, - }); - plugins.uiActions.addTriggerAction(CONTEXT_MENU_TRIGGER, addToNewCaseAction); - const addToExistingCaseAction = createAddToExistingCaseLensAction({ core, plugins, diff --git a/x-pack/plugins/cases/public/components/visualizations/actions/translations.ts b/x-pack/plugins/cases/public/components/visualizations/actions/translations.ts index ed7ee1370d875..1039700ba67ae 100644 --- a/x-pack/plugins/cases/public/components/visualizations/actions/translations.ts +++ b/x-pack/plugins/cases/public/components/visualizations/actions/translations.ts @@ -14,16 +14,9 @@ export const ADD_TO_CASE_SUCCESS = i18n.translate( } ); -export const ADD_TO_NEW_CASE_DISPLAYNAME = i18n.translate( - 'xpack.cases.actions.visualizationActions.addToNewCase.displayName', - { - defaultMessage: 'Add to new case', - } -); - export const ADD_TO_EXISTING_CASE_DISPLAYNAME = i18n.translate( 'xpack.cases.actions.visualizationActions.addToExistingCase.displayName', { - defaultMessage: 'Add to existing case', + defaultMessage: 'Add to case', } ); diff --git a/x-pack/plugins/dashboard_enhanced/public/services/drilldowns/actions/flyout_create_drilldown/flyout_create_drilldown.tsx b/x-pack/plugins/dashboard_enhanced/public/services/drilldowns/actions/flyout_create_drilldown/flyout_create_drilldown.tsx index 2c6bd8074a689..6fd7d7602ebec 100644 --- a/x-pack/plugins/dashboard_enhanced/public/services/drilldowns/actions/flyout_create_drilldown/flyout_create_drilldown.tsx +++ b/x-pack/plugins/dashboard_enhanced/public/services/drilldowns/actions/flyout_create_drilldown/flyout_create_drilldown.tsx @@ -7,7 +7,6 @@ import { apiHasDynamicActions, - embeddableEnhancedDrilldownGrouping, type HasDynamicActions, } from '@kbn/embeddable-enhanced-plugin/public'; import { CONTEXT_MENU_TRIGGER } from '@kbn/embeddable-plugin/public'; @@ -59,7 +58,6 @@ export class FlyoutCreateDrilldownAction implements Action public readonly type = OPEN_FLYOUT_ADD_DRILLDOWN; public readonly id = OPEN_FLYOUT_ADD_DRILLDOWN; public order = 12; - public grouping = embeddableEnhancedDrilldownGrouping; constructor(protected readonly params: OpenFlyoutAddDrilldownParams) {} diff --git a/x-pack/plugins/dashboard_enhanced/public/services/drilldowns/actions/flyout_edit_drilldown/flyout_edit_drilldown.tsx b/x-pack/plugins/dashboard_enhanced/public/services/drilldowns/actions/flyout_edit_drilldown/flyout_edit_drilldown.tsx index bf5588e762574..a6f08d9921ca5 100644 --- a/x-pack/plugins/dashboard_enhanced/public/services/drilldowns/actions/flyout_edit_drilldown/flyout_edit_drilldown.tsx +++ b/x-pack/plugins/dashboard_enhanced/public/services/drilldowns/actions/flyout_edit_drilldown/flyout_edit_drilldown.tsx @@ -26,7 +26,6 @@ import { import { CONTEXT_MENU_TRIGGER } from '@kbn/embeddable-plugin/public'; import { apiHasDynamicActions, - embeddableEnhancedDrilldownGrouping, type HasDynamicActions, } from '@kbn/embeddable-enhanced-plugin/public'; import { StartServicesGetter } from '@kbn/kibana-utils-plugin/public'; @@ -54,7 +53,6 @@ export class FlyoutEditDrilldownAction implements Action { public readonly type = OPEN_FLYOUT_EDIT_DRILLDOWN; public readonly id = OPEN_FLYOUT_EDIT_DRILLDOWN; public order = 10; - public grouping = embeddableEnhancedDrilldownGrouping; constructor(protected readonly params: FlyoutEditDrilldownParams) {} diff --git a/x-pack/plugins/lens/public/app_plugin/lens_top_nav.tsx b/x-pack/plugins/lens/public/app_plugin/lens_top_nav.tsx index 891f9b4ae5a21..ae1a8fec7a88e 100644 --- a/x-pack/plugins/lens/public/app_plugin/lens_top_nav.tsx +++ b/x-pack/plugins/lens/public/app_plugin/lens_top_nav.tsx @@ -161,7 +161,7 @@ function getLensTopNavConfig(options: { if (actions.getUnderlyingDataUrl.visible) { const exploreDataInDiscoverLabel = i18n.translate('xpack.lens.app.exploreDataInDiscover', { - defaultMessage: 'Explore data in Discover', + defaultMessage: 'Explore in Discover', }); topNavMenu.push({ diff --git a/x-pack/plugins/lens/public/trigger_actions/open_in_discover_action.ts b/x-pack/plugins/lens/public/trigger_actions/open_in_discover_action.ts index 13a44055a1cfb..9b48c41e41856 100644 --- a/x-pack/plugins/lens/public/trigger_actions/open_in_discover_action.ts +++ b/x-pack/plugins/lens/public/trigger_actions/open_in_discover_action.ts @@ -26,8 +26,8 @@ export const createOpenInDiscoverAction = ( order: 19, // right after Inspect which is 20 getIconType: () => 'popout', getDisplayName: () => - i18n.translate('xpack.lens.app.exploreDataInDiscover', { - defaultMessage: 'Explore data in Discover', + i18n.translate('xpack.lens.action.exploreInDiscover', { + defaultMessage: 'Explore in Discover', }), getHref: async (context: EmbeddableApiContext) => { const { getHref } = await getDiscoverHelpersAsync(); diff --git a/x-pack/plugins/ml/public/ui_actions/open_vis_in_ml_action.tsx b/x-pack/plugins/ml/public/ui_actions/open_vis_in_ml_action.tsx index e4ce56e8f5a54..84f053aafcaf5 100644 --- a/x-pack/plugins/ml/public/ui_actions/open_vis_in_ml_action.tsx +++ b/x-pack/plugins/ml/public/ui_actions/open_vis_in_ml_action.tsx @@ -28,7 +28,7 @@ export function createVisToADJobAction( }, getDisplayName: () => i18n.translate('xpack.ml.actions.createADJobFromLens', { - defaultMessage: 'Create anomaly detection job', + defaultMessage: 'Detect anomalies', }), async execute({ embeddable }: EmbeddableApiContext) { if (!embeddable) { diff --git a/x-pack/plugins/translations/translations/fr-FR.json b/x-pack/plugins/translations/translations/fr-FR.json index a0057befbed14..8d796f04cf9a4 100644 --- a/x-pack/plugins/translations/translations/fr-FR.json +++ b/x-pack/plugins/translations/translations/fr-FR.json @@ -1175,7 +1175,6 @@ "customIntegrationsPackage.validations.integrationName.lowerCaseError": "Le nom d'une intégration doit être en minuscules.", "customIntegrationsPackage.validations.integrationName.requiredError": "Une intégration doit obligatoirement porter un nom.", "dashboard.addPanel.newEmbeddableAddedSuccessMessageTitle": "{savedObjectName} a été ajouté.", - "dashboard.addPanel.savedObjectAddedToContainerSuccessMessageTitle": "{savedObjectName} a été ajouté.", "dashboard.dashboardListingEditErrorTitle.duplicateWarning": "L'enregistrement de \"{value}\" crée un doublon de titre", "dashboard.dashboardWasNotSavedDangerMessage": "Le tableau de bord \"{dashTitle}\" n'a pas été enregistré. Erreur : {errorMessage}.", "dashboard.listing.createNewDashboard.newToKibanaDescription": "Vous êtes nouveau sur Kibana ? {sampleDataInstallLink} pour découvrir l'application.", @@ -1186,7 +1185,6 @@ "dashboard.noMatchRoute.bannerText": "L'application de tableau de bord ne reconnaît pas ce chemin : {route}.", "dashboard.panel.addToLibrary.errorMessage": "Une erreur s'est produite lors de l'ajout du panneau {panelTitle} à la bibliothèque", "dashboard.panel.addToLibrary.successMessage": "Le panneau {panelTitle} a été ajouté à la bibliothèque", - "dashboard.panel.replacePanel.flyoutHeader": "Remplacer le panneau {panelName} par :", "dashboard.panel.unableToMigratePanelDataForSixThreeZeroErrorMessage": "Impossible de migrer les données du panneau pour une rétro-compatibilité \"6.3.0\". Le panneau ne contient pas le champ attendu : {key}.", "dashboard.panel.unlinkFromLibrary.failureMessage": "Une erreur s'est produite lors de la dissociation du panneau {panelTitle} de la bibliothèque.", "dashboard.panel.unlinkFromLibrary.successMessage": "Le panneau {panelTitle} n'est plus connecté à la bibliothèque.", @@ -1200,8 +1198,6 @@ "dashboard.actions.downloadOptionsUnsavedFilename": "sans titre", "dashboard.actions.toggleExpandPanelMenuItem.expandedDisplayName": "Minimiser", "dashboard.actions.toggleExpandPanelMenuItem.notExpandedDisplayName": "Maximiser le panneau", - "dashboard.addPanel.noMatchingObjectsMessage": "Aucun objet correspondant trouvé.", - "dashboard.addPanel.panelAddedToContainerSuccessMessageTitle": "Un panneau a été ajouté", "dashboard.addPanelMenuTrigger.description": "Une nouvelle action apparaîtra dans le menu Ajouter un panneau du tableau de bord", "dashboard.addPanelMenuTrigger.title": "Menu Ajouter un panneau", "dashboard.appLeaveConfirmModal.cancelButtonLabel": "Annuler", @@ -1300,7 +1296,6 @@ "dashboard.panel.LibraryNotification": "Notification de la bibliothèque", "dashboard.panel.libraryNotification.ariaLabel": "Afficher les informations de la bibliothèque et dissocier ce panneau", "dashboard.panel.libraryNotification.toolTip": "La modification de ce panneau pourrait affecter d’autres tableaux de bord. Pour modifier ce panneau uniquement, dissociez-le de la bibliothèque.", - "dashboard.panel.removePanel.replacePanel": "Remplacer le panneau", "dashboard.panel.title.clonedTag": "copier", "dashboard.panel.unableToMigratePanelDataForSixOneZeroErrorMessage": "Impossible de migrer les données du panneau pour une rétro-compatibilité \"6.1.0\". Le panneau ne contient pas les champs de colonne et/ou de ligne attendus.", "dashboard.panel.unlinkFromLibrary": "Dissocier de la bibliothèque", @@ -11899,7 +11894,6 @@ "xpack.cases.actions.tags.selectNone": "Sélectionner aucun", "xpack.cases.actions.viewCase": "Afficher le cas", "xpack.cases.actions.visualizationActions.addToExistingCase.displayName": "Ajouter à un cas existant", - "xpack.cases.actions.visualizationActions.addToNewCase.displayName": "Ajouter au nouveau cas", "xpack.cases.addConnector.title": "Ajouter un connecteur", "xpack.cases.allCases.actions": "Actions", "xpack.cases.allCases.comments": "Commentaires", diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index 06a3c6238fb94..c3961d056a76a 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -1175,7 +1175,6 @@ "customIntegrationsPackage.validations.integrationName.lowerCaseError": "統合名は小文字にしてください。", "customIntegrationsPackage.validations.integrationName.requiredError": "統合名は必須です。", "dashboard.addPanel.newEmbeddableAddedSuccessMessageTitle": "{savedObjectName} が追加されました", - "dashboard.addPanel.savedObjectAddedToContainerSuccessMessageTitle": "{savedObjectName} が追加されました", "dashboard.dashboardListingEditErrorTitle.duplicateWarning": "\"{value}\"を保存すると、タイトルが重複します", "dashboard.dashboardWasNotSavedDangerMessage": "ダッシュボード「{dashTitle}」が保存されませんでした。エラー:{errorMessage}", "dashboard.listing.createNewDashboard.newToKibanaDescription": "Kibanaは初心者ですか?{sampleDataInstallLink}してお試しください。", @@ -1186,7 +1185,6 @@ "dashboard.noMatchRoute.bannerText": "ダッシュボードアプリケーションはこのルート{route}を認識できません。", "dashboard.panel.addToLibrary.errorMessage": "パネル\"{panelTitle}\"をライブラリに追加しているときにエラーが発生しました。", "dashboard.panel.addToLibrary.successMessage": "パネル\"{panelTitle}\"はライブラリに追加されました", - "dashboard.panel.replacePanel.flyoutHeader": "パネル\"{panelName}\"を次で置換:", "dashboard.panel.unableToMigratePanelDataForSixThreeZeroErrorMessage": "「6.3.0」のダッシュボードの互換性のため、パネルデータを移行できませんでした。パネルに必要なフィールドがありません:{key}", "dashboard.panel.unlinkFromLibrary.failureMessage": "\"{panelTitle}\"をライブラリからリンク解除しているときにエラーが発生しました。", "dashboard.panel.unlinkFromLibrary.successMessage": "パネル\"{panelTitle}\"はライブラリに接続されていません。", @@ -1200,8 +1198,6 @@ "dashboard.actions.downloadOptionsUnsavedFilename": "無題", "dashboard.actions.toggleExpandPanelMenuItem.expandedDisplayName": "最小化", "dashboard.actions.toggleExpandPanelMenuItem.notExpandedDisplayName": "パネルを最大化", - "dashboard.addPanel.noMatchingObjectsMessage": "一致するオブジェクトが見つかりませんでした。", - "dashboard.addPanel.panelAddedToContainerSuccessMessageTitle": "パネルが追加されました", "dashboard.addPanelMenuTrigger.description": "新しいアクションは、ダッシュボードのパネルの追加メニューに表示されます", "dashboard.addPanelMenuTrigger.title": "パネルの追加メニュー", "dashboard.appLeaveConfirmModal.cancelButtonLabel": "キャンセル", @@ -1300,7 +1296,6 @@ "dashboard.panel.LibraryNotification": "ライブラリ通知", "dashboard.panel.libraryNotification.ariaLabel": "ライブラリ情報を表示し、このパネルのリンクを解除します", "dashboard.panel.libraryNotification.toolTip": "このパネルを編集すると、他のダッシュボードに影響する場合があります。このパネルのみを変更するには、ライブラリからリンクを解除します。", - "dashboard.panel.removePanel.replacePanel": "パネルの交換", "dashboard.panel.title.clonedTag": "コピー", "dashboard.panel.unableToMigratePanelDataForSixOneZeroErrorMessage": "「6.1.0」のダッシュボードの互換性のため、パネルデータを移行できませんでした。パネルには想定された列または行フィールドがありません", "dashboard.panel.unlinkFromLibrary": "ライブラリからのリンクを解除", @@ -11879,7 +11874,6 @@ "xpack.cases.actions.tags.selectNone": "どれも選択しません", "xpack.cases.actions.viewCase": "ケースの表示", "xpack.cases.actions.visualizationActions.addToExistingCase.displayName": "既存のケースに追加", - "xpack.cases.actions.visualizationActions.addToNewCase.displayName": "新しいケースに追加", "xpack.cases.addConnector.title": "コネクターの追加", "xpack.cases.allCases.actions": "アクション", "xpack.cases.allCases.comments": "コメント", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index 12c75c281fbbf..058bbf2c6606c 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -1177,7 +1177,6 @@ "customIntegrationsPackage.validations.integrationName.lowerCaseError": "集成名称应为小写。", "customIntegrationsPackage.validations.integrationName.requiredError": "集成名称必填。", "dashboard.addPanel.newEmbeddableAddedSuccessMessageTitle": "{savedObjectName} 已添加", - "dashboard.addPanel.savedObjectAddedToContainerSuccessMessageTitle": "{savedObjectName} 已添加", "dashboard.dashboardListingEditErrorTitle.duplicateWarning": "保存“{value}”会创建重复的标题", "dashboard.dashboardWasNotSavedDangerMessage": "仪表板“{dashTitle}”未保存。错误:{errorMessage}", "dashboard.listing.createNewDashboard.newToKibanaDescription": "Kibana 新手?{sampleDataInstallLink}来试用一下。", @@ -1188,7 +1187,6 @@ "dashboard.noMatchRoute.bannerText": "Dashboard 应用程序无法识别此路由:{route}。", "dashboard.panel.addToLibrary.errorMessage": "将面板 {panelTitle} 添加到该库时遇到错误", "dashboard.panel.addToLibrary.successMessage": "面板 {panelTitle} 已添加到该库", - "dashboard.panel.replacePanel.flyoutHeader": "将面板 {panelName} 替换为:", "dashboard.panel.unableToMigratePanelDataForSixThreeZeroErrorMessage": "无法迁移用于“6.3.0”向后兼容的面板数据,面板不包含所需字段:{key}", "dashboard.panel.unlinkFromLibrary.failureMessage": "从该库中取消链接 {panelTitle} 时出错。", "dashboard.panel.unlinkFromLibrary.successMessage": "面板 {panelTitle} 不再与该库连接。", @@ -1202,8 +1200,6 @@ "dashboard.actions.downloadOptionsUnsavedFilename": "未命名", "dashboard.actions.toggleExpandPanelMenuItem.expandedDisplayName": "最小化", "dashboard.actions.toggleExpandPanelMenuItem.notExpandedDisplayName": "最大化面板", - "dashboard.addPanel.noMatchingObjectsMessage": "未找到任何匹配对象。", - "dashboard.addPanel.panelAddedToContainerSuccessMessageTitle": "已添加一个面板", "dashboard.addPanelMenuTrigger.description": "一个新操作将在仪表板的添加面板菜单中显示出来", "dashboard.addPanelMenuTrigger.title": "添加面板菜单", "dashboard.appLeaveConfirmModal.cancelButtonLabel": "取消", @@ -1302,7 +1298,6 @@ "dashboard.panel.LibraryNotification": "库通知", "dashboard.panel.libraryNotification.ariaLabel": "查看库信息并取消链接此面板", "dashboard.panel.libraryNotification.toolTip": "编辑此面板可能会影响其他仪表板。要仅更改此面板,请取消其与库的链接。", - "dashboard.panel.removePanel.replacePanel": "替换面板", "dashboard.panel.title.clonedTag": "副本", "dashboard.panel.unableToMigratePanelDataForSixOneZeroErrorMessage": "无法迁移用于“6.1.0”向后兼容的面板数据,面板不包含所需的列和/或行字段", "dashboard.panel.unlinkFromLibrary": "取消与库的链接", @@ -11903,7 +11898,6 @@ "xpack.cases.actions.tags.selectNone": "不选择任何内容", "xpack.cases.actions.viewCase": "查看案例", "xpack.cases.actions.visualizationActions.addToExistingCase.displayName": "添加到现有案例", - "xpack.cases.actions.visualizationActions.addToNewCase.displayName": "添加到新案例", "xpack.cases.addConnector.title": "添加连接器", "xpack.cases.allCases.actions": "操作", "xpack.cases.allCases.comments": "注释", diff --git a/x-pack/test/accessibility/apps/group1/dashboard_panel_options.ts b/x-pack/test/accessibility/apps/group1/dashboard_panel_options.ts index a6d3fea21a4e2..991be3b49bb40 100644 --- a/x-pack/test/accessibility/apps/group1/dashboard_panel_options.ts +++ b/x-pack/test/accessibility/apps/group1/dashboard_panel_options.ts @@ -121,6 +121,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { it('dashboard panel - Create drilldown panel', async () => { await dashboardPanelActions.toggleContextMenu(header); + await testSubjects.click('embeddablePanelMore-mainMenu'); await testSubjects.click('embeddablePanelAction-OPEN_FLYOUT_ADD_DRILLDOWN'); await a11y.testAppSnapshot(); await testSubjects.click('actionFactoryItem-DASHBOARD_TO_DASHBOARD_DRILLDOWN'); @@ -136,6 +137,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { it('dashboard panel - manage drilldown', async () => { await dashboardPanelActions.toggleContextMenu(header); + await testSubjects.click('embeddablePanelMore-mainMenu'); await testSubjects.click('embeddablePanelAction-OPEN_FLYOUT_EDIT_DRILLDOWN'); await a11y.testAppSnapshot(); await testSubjects.click('euiFlyoutCloseButton'); diff --git a/x-pack/test/functional/apps/dashboard/group3/drilldowns/dashboard_to_dashboard_drilldown.ts b/x-pack/test/functional/apps/dashboard/group3/drilldowns/dashboard_to_dashboard_drilldown.ts index a29b61fec5609..95ea2dc42bc39 100644 --- a/x-pack/test/functional/apps/dashboard/group3/drilldowns/dashboard_to_dashboard_drilldown.ts +++ b/x-pack/test/functional/apps/dashboard/group3/drilldowns/dashboard_to_dashboard_drilldown.ts @@ -46,6 +46,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { // create drilldown await dashboardPanelActions.openContextMenu(); + await dashboardPanelActions.clickContextMenuMoreItem(); await dashboardDrilldownPanelActions.expectExistsCreateDrilldownAction(); await dashboardDrilldownPanelActions.clickCreateDrilldown(); await dashboardDrilldownsManage.expectsCreateDrilldownFlyoutOpen(); @@ -277,6 +278,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { // delete drilldown await PageObjects.dashboard.switchToEditMode(); await dashboardPanelActions.openContextMenu(); + await dashboardPanelActions.clickContextMenuMoreItem(); await dashboardDrilldownPanelActions.expectExistsManageDrilldownsAction(); await dashboardDrilldownPanelActions.clickManageDrilldowns(); await dashboardDrilldownsManage.expectsManageDrilldownsFlyoutOpen(); diff --git a/x-pack/test/functional/apps/dashboard/group3/drilldowns/dashboard_to_url_drilldown.ts b/x-pack/test/functional/apps/dashboard/group3/drilldowns/dashboard_to_url_drilldown.ts index 24e9a249377fa..e7c8a0819fd1a 100644 --- a/x-pack/test/functional/apps/dashboard/group3/drilldowns/dashboard_to_url_drilldown.ts +++ b/x-pack/test/functional/apps/dashboard/group3/drilldowns/dashboard_to_url_drilldown.ts @@ -33,6 +33,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { // create drilldown await dashboardPanelActions.openContextMenu(); + await dashboardPanelActions.clickContextMenuMoreItem(); await dashboardDrilldownPanelActions.expectExistsCreateDrilldownAction(); await dashboardDrilldownPanelActions.clickCreateDrilldown(); await dashboardDrilldownsManage.expectsCreateDrilldownFlyoutOpen(); diff --git a/x-pack/test/functional_with_es_ssl/apps/cases/group2/attachment_framework.ts b/x-pack/test/functional_with_es_ssl/apps/cases/group2/attachment_framework.ts index a8949fc849812..8909d8cea2ec5 100644 --- a/x-pack/test/functional_with_es_ssl/apps/cases/group2/attachment_framework.ts +++ b/x-pack/test/functional_with_es_ssl/apps/cases/group2/attachment_framework.ts @@ -396,7 +396,8 @@ export default ({ getPageObject, getService }: FtrProviderContext) => { await testSubjects.click('embeddablePanelToggleMenuIcon'); await testSubjects.click('embeddablePanelMore-mainMenu'); - await testSubjects.click('embeddablePanelAction-embeddable_addToNewCase'); + await testSubjects.click('embeddablePanelAction-embeddable_addToExistingCase'); + await testSubjects.click('cases-table-add-case-filter-bar'); await cases.create.createCase({ title: caseTitle, diff --git a/x-pack/test_serverless/functional/test_suites/common/discover/embeddable/_saved_search_embeddable.ts b/x-pack/test_serverless/functional/test_suites/common/discover/embeddable/_saved_search_embeddable.ts index 386d387d7ad6e..591b34da48b57 100644 --- a/x-pack/test_serverless/functional/test_suites/common/discover/embeddable/_saved_search_embeddable.ts +++ b/x-pack/test_serverless/functional/test_suites/common/discover/embeddable/_saved_search_embeddable.ts @@ -12,8 +12,6 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { const browser = getService('browser'); const dataGrid = getService('dataGrid'); const dashboardAddPanel = getService('dashboardAddPanel'); - const dashboardPanelActions = getService('dashboardPanelActions'); - const dashboardReplacePanel = getService('dashboardReplacePanel'); const filterBar = getService('filterBar'); const queryBar = getService('queryBar'); const esArchiver = getService('esArchiver'); @@ -140,18 +138,6 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { ); }); - it('should replace a panel with a saved search', async () => { - await dashboardAddPanel.addVisualization('Rendering Test: datatable'); - await PageObjects.header.waitUntilLoadingHasFinished(); - await PageObjects.dashboard.waitForRenderComplete(); - await dashboardPanelActions.replacePanelByTitle('Rendering Test: datatable'); - await dashboardReplacePanel.replaceEmbeddable('Rendering-Test:-saved-search'); - await PageObjects.header.waitUntilLoadingHasFinished(); - await PageObjects.dashboard.waitForRenderComplete(); - await testSubjects.missingOrFail('embeddableError'); - expect(await PageObjects.discover.getSavedSearchDocumentCount()).to.be('4,633 documents'); - }); - it('should not show the full screen button', async () => { await addSearchEmbeddableToDashboard(); await testSubjects.missingOrFail('dataGridFullScreenButton'); diff --git a/x-pack/test_serverless/functional/test_suites/observability/cases/attachment_framework.ts b/x-pack/test_serverless/functional/test_suites/observability/cases/attachment_framework.ts index a06bbf97d8f34..dd157b9aa162f 100644 --- a/x-pack/test_serverless/functional/test_suites/observability/cases/attachment_framework.ts +++ b/x-pack/test_serverless/functional/test_suites/observability/cases/attachment_framework.ts @@ -57,7 +57,8 @@ export default ({ getPageObject, getService }: FtrProviderContext) => { await testSubjects.click('embeddablePanelToggleMenuIcon'); await testSubjects.click('embeddablePanelMore-mainMenu'); - await testSubjects.click('embeddablePanelAction-embeddable_addToNewCase'); + await testSubjects.click('embeddablePanelAction-embeddable_addToExistingCase'); + await testSubjects.click('cases-table-add-case-filter-bar'); await testSubjects.existOrFail('create-case-flyout'); diff --git a/x-pack/test_serverless/functional/test_suites/search/cases/attachment_framework.ts b/x-pack/test_serverless/functional/test_suites/search/cases/attachment_framework.ts index 5285579c1f326..044782083b292 100644 --- a/x-pack/test_serverless/functional/test_suites/search/cases/attachment_framework.ts +++ b/x-pack/test_serverless/functional/test_suites/search/cases/attachment_framework.ts @@ -55,7 +55,6 @@ export default ({ getPageObject, getService }: FtrProviderContext) => { it('does not show actions to add lens visualization to case', async () => { await testSubjects.click('embeddablePanelToggleMenuIcon'); await testSubjects.click('embeddablePanelMore-mainMenu'); - await testSubjects.missingOrFail('embeddablePanelAction-embeddable_addToNewCase'); await testSubjects.missingOrFail('embeddablePanelAction-embeddable_addToExistingCase'); }); }); diff --git a/x-pack/test_serverless/functional/test_suites/security/ftr/cases/attachment_framework.ts b/x-pack/test_serverless/functional/test_suites/security/ftr/cases/attachment_framework.ts index 85a78cef48a86..e271013c410a7 100644 --- a/x-pack/test_serverless/functional/test_suites/security/ftr/cases/attachment_framework.ts +++ b/x-pack/test_serverless/functional/test_suites/security/ftr/cases/attachment_framework.ts @@ -50,7 +50,8 @@ export default ({ getPageObject, getService }: FtrProviderContext) => { await testSubjects.click('embeddablePanelToggleMenuIcon'); await testSubjects.click('embeddablePanelMore-mainMenu'); - await testSubjects.click('embeddablePanelAction-embeddable_addToNewCase'); + await testSubjects.click('embeddablePanelAction-embeddable_addToExistingCase'); + await testSubjects.click('cases-table-add-case-filter-bar'); await testSubjects.existOrFail('create-case-flyout');