Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[8.x] [Dashboard] Cleanup services (#193644) #194210

Merged
merged 1 commit into from
Sep 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 33 additions & 3 deletions src/plugins/dashboard/jest_setup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,43 @@
* License v3.0 only", or the "Server Side Public License, v 1".
*/

import { setStubDashboardServices } from './public/services/mocks';

/**
* CAUTION: Be very mindful of the things you import in to this `jest_setup` file - anything that is imported
* here (either directly or implicitly through dependencies) will be **unable** to be mocked elsewhere!
*
* Refer to the "Caution" section here:
* https://jestjs.io/docs/jest-object#jestmockmodulename-factory-options
*/
setStubDashboardServices();
import {
mockDashboardBackupService,
mockDashboardContentManagementCache,
mockDashboardContentManagementService,
setStubKibanaServices,
} from './public/services/mocks';

// Start the kibana services with stubs
setStubKibanaServices();

// Mock the dashboard services
jest.mock('./public/services/dashboard_content_management_service', () => {
return {
getDashboardContentManagementCache: () => mockDashboardContentManagementCache,
getDashboardContentManagementService: () => mockDashboardContentManagementService,
};
});

jest.mock('./public/services/dashboard_backup_service', () => {
return {
getDashboardBackupService: () => mockDashboardBackupService,
};
});

jest.mock('./public/services/dashboard_recently_accessed_service', () => {
return {
getDashboardRecentlyAccessedService: () => ({
add: jest.fn(),
get: jest.fn(),
get$: jest.fn(),
}),
};
});
Original file line number Diff line number Diff line change
Expand Up @@ -8,34 +8,36 @@
*/

import React from 'react';

import { PresentationContainer } from '@kbn/presentation-containers';
import {
apiCanAccessViewMode,
apiHasLibraryTransforms,
EmbeddableApiContext,
getPanelTitle,
PublishesPanelTitle,
CanAccessViewMode,
getInheritedViewMode,
EmbeddableApiContext,
HasInPlaceLibraryTransforms,
HasLibraryTransforms,
HasParentApi,
HasType,
HasTypeDisplayName,
apiHasType,
HasUniqueId,
HasParentApi,
apiHasUniqueId,
apiHasParentApi,
HasInPlaceLibraryTransforms,
PublishesPanelTitle,
apiCanAccessViewMode,
apiHasInPlaceLibraryTransforms,
apiHasLibraryTransforms,
apiHasParentApi,
apiHasType,
apiHasUniqueId,
getInheritedViewMode,
getPanelTitle,
} from '@kbn/presentation-publishing';
import {
OnSaveProps,
SavedObjectSaveModal,
SaveResult,
SavedObjectSaveModal,
showSaveModal,
} from '@kbn/saved-objects-plugin/public';
import { Action, IncompatibleActionError } from '@kbn/ui-actions-plugin/public';
import { PresentationContainer } from '@kbn/presentation-containers';
import { pluginServices } from '../services/plugin_services';

import { coreServices } from '../services/kibana_services';
import { dashboardAddToLibraryActionStrings } from './_dashboard_actions_strings';

export const ACTION_ADD_TO_LIBRARY = 'saveToLibrary';
Expand All @@ -62,14 +64,6 @@ export class AddToLibraryAction implements Action<EmbeddableApiContext> {
public readonly id = ACTION_ADD_TO_LIBRARY;
public order = 8;

private toastsService;

constructor() {
({
notifications: { toasts: this.toastsService },
} = pluginServices.getServices());
}

public getDisplayName({ embeddable }: EmbeddableApiContext) {
if (!isApiCompatible(embeddable)) throw new IncompatibleActionError();
return dashboardAddToLibraryActionStrings.getDisplayName();
Expand Down Expand Up @@ -134,12 +128,12 @@ export class AddToLibraryAction implements Action<EmbeddableApiContext> {
initialState: byRefState,
});
}
this.toastsService.addSuccess({
coreServices.notifications.toasts.addSuccess({
title: dashboardAddToLibraryActionStrings.getSuccessMessage(title ? `'${title}'` : ''),
'data-test-subj': 'addPanelToLibrarySuccess',
});
} catch (e) {
this.toastsService.addDanger({
coreServices.notifications.toasts.addDanger({
title: dashboardAddToLibraryActionStrings.getErrorMessage(title),
'data-test-subj': 'addPanelToLibraryError',
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,6 @@ export class ClonePanelAction implements Action<EmbeddableApiContext> {
public readonly id = ACTION_CLONE_PANEL;
public order = 45;

constructor() {}

public getDisplayName({ embeddable }: EmbeddableApiContext) {
if (!isApiCompatible(embeddable)) throw new IncompatibleActionError();
return dashboardClonePanelActionStrings.getDisplayName();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,26 +9,26 @@

import React from 'react';

import { CoreStart } from '@kbn/core-lifecycle-browser';
import {
apiIsOfType,
apiHasUniqueId,
apiHasParentApi,
apiPublishesSavedObjectId,
HasType,
EmbeddableApiContext,
HasUniqueId,
HasParentApi,
HasType,
HasUniqueId,
PublishesSavedObjectId,
apiHasParentApi,
apiHasUniqueId,
apiIsOfType,
apiPublishesSavedObjectId,
} from '@kbn/presentation-publishing';
import { toMountPoint } from '@kbn/react-kibana-mount';
import { Action, IncompatibleActionError } from '@kbn/ui-actions-plugin/public';

import { DASHBOARD_CONTAINER_TYPE } from '../dashboard_container';
import { DashboardApi } from '../dashboard_api/types';
import { pluginServices } from '../services/plugin_services';
import { CopyToDashboardModal } from './copy_to_dashboard_modal';
import { DASHBOARD_CONTAINER_TYPE } from '../dashboard_container';
import { coreServices } from '../services/kibana_services';
import { getDashboardCapabilities } from '../utils/get_dashboard_capabilities';
import { dashboardCopyToDashboardActionStrings } from './_dashboard_actions_strings';
import { CopyToDashboardModal } from './copy_to_dashboard_modal';

export const ACTION_COPY_TO_DASHBOARD = 'copyToDashboard';

Expand Down Expand Up @@ -60,16 +60,6 @@ export class CopyToDashboardAction implements Action<EmbeddableApiContext> {
public readonly id = ACTION_COPY_TO_DASHBOARD;
public order = 1;

private dashboardCapabilities;
private openModal;

constructor(private core: CoreStart) {
({
dashboardCapabilities: this.dashboardCapabilities,
overlays: { openModal: this.openModal },
} = pluginServices.getServices());
}

public getDisplayName({ embeddable }: EmbeddableApiContext) {
if (!apiIsCompatible(embeddable)) throw new IncompatibleActionError();

Expand All @@ -84,15 +74,15 @@ export class CopyToDashboardAction implements Action<EmbeddableApiContext> {
public async isCompatible({ embeddable }: EmbeddableApiContext) {
if (!apiIsCompatible(embeddable)) return false;
const { createNew: canCreateNew, showWriteControls: canEditExisting } =
this.dashboardCapabilities;
getDashboardCapabilities();
return Boolean(canCreateNew || canEditExisting);
}

public async execute({ embeddable }: EmbeddableApiContext) {
if (!apiIsCompatible(embeddable)) throw new IncompatibleActionError();

const { theme, i18n } = this.core;
const session = this.openModal(
const { theme, i18n } = coreServices;
const session = coreServices.overlays.openModal(
toMountPoint(<CopyToDashboardModal closeModal={() => session.close()} api={embeddable} />, {
theme,
i18n,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,12 @@ import { EmbeddablePackageState, PanelNotFoundError } from '@kbn/embeddable-plug
import { apiHasSnapshottableState } from '@kbn/presentation-containers/interfaces/serialized_state';
import { LazyDashboardPicker, withSuspense } from '@kbn/presentation-util-plugin/public';
import { omit } from 'lodash';
import React, { useCallback, useState } from 'react';
import { createDashboardEditUrl, CREATE_NEW_DASHBOARD_URL } from '../dashboard_constants';
import { pluginServices } from '../services/plugin_services';
import { CopyToDashboardAPI } from './copy_to_dashboard_action';
import React, { useCallback, useMemo, useState } from 'react';
import { CREATE_NEW_DASHBOARD_URL, createDashboardEditUrl } from '../dashboard_constants';
import { embeddableService } from '../services/kibana_services';
import { getDashboardCapabilities } from '../utils/get_dashboard_capabilities';
import { dashboardCopyToDashboardActionStrings } from './_dashboard_actions_strings';
import { CopyToDashboardAPI } from './copy_to_dashboard_action';

interface CopyToDashboardModalProps {
api: CopyToDashboardAPI;
Expand All @@ -36,11 +37,11 @@ interface CopyToDashboardModalProps {
const DashboardPicker = withSuspense(LazyDashboardPicker);

export function CopyToDashboardModal({ api, closeModal }: CopyToDashboardModalProps) {
const {
embeddable: { getStateTransfer },
dashboardCapabilities: { createNew: canCreateNew, showWriteControls: canEditExisting },
} = pluginServices.getServices();
const stateTransfer = getStateTransfer();
const stateTransfer = useMemo(() => embeddableService.getStateTransfer(), []);
const { createNew: canCreateNew, showWriteControls: canEditExisting } = useMemo(
() => getDashboardCapabilities(),
[]
);

const [dashboardOption, setDashboardOption] = useState<'new' | 'existing'>('existing');
const [selectedDashboard, setSelectedDashboard] = useState<{ id: string; name: string } | null>(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,6 @@ export class ExpandPanelAction implements Action<EmbeddableApiContext> {
public readonly id = ACTION_EXPAND_PANEL;
public order = 7;

constructor() {}

public getDisplayName({ embeddable }: EmbeddableApiContext) {
if (!isApiCompatible(embeddable)) throw new IncompatibleActionError();
return embeddable.parentApi.expandedPanelId.value
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,16 @@ import { downloadMultipleAs } from '@kbn/share-plugin/public';
import { Action, IncompatibleActionError } from '@kbn/ui-actions-plugin/public';

import {
apiHasInspectorAdapters,
HasInspectorAdapters,
apiHasInspectorAdapters,
type Adapters,
} from '@kbn/inspector-plugin/public';
import {
EmbeddableApiContext,
getPanelTitle,
PublishesPanelTitle,
getPanelTitle,
} from '@kbn/presentation-publishing';
import { pluginServices } from '../services/plugin_services';
import { coreServices, fieldFormatService } from '../services/kibana_services';
import { dashboardExportCsvActionStrings } from './_dashboard_actions_strings';

export const ACTION_EXPORT_CSV = 'ACTION_EXPORT_CSV';
Expand All @@ -43,16 +43,6 @@ export class ExportCSVAction implements Action<ExportContext> {
public readonly type = ACTION_EXPORT_CSV;
public readonly order = 18; // right after Export in discover which is 19

private fieldFormats;
private uiSettings;

constructor() {
({
data: { fieldFormats: this.fieldFormats },
settings: { uiSettings: this.uiSettings },
} = pluginServices.getServices());
}

public getIconType() {
return 'exportAction';
}
Expand All @@ -70,9 +60,7 @@ export class ExportCSVAction implements Action<ExportContext> {
};

private getFormatter = (): FormatFactory | undefined => {
if (this.fieldFormats) {
return this.fieldFormats.deserialize;
}
return fieldFormatService.deserialize;
};

private getDataTableContent = (adapters: Adapters | undefined) => {
Expand Down Expand Up @@ -105,8 +93,8 @@ export class ExportCSVAction implements Action<ExportContext> {

memo[`${getPanelTitle(embeddable) || untitledFilename}${postFix}.csv`] = {
content: exporters.datatableToCSV(datatable, {
csvSeparator: this.uiSettings.get('csv:separator', ','),
quoteValues: this.uiSettings.get('csv:quoteValues', true),
csvSeparator: coreServices.uiSettings.get('csv:separator', ','),
quoteValues: coreServices.uiSettings.get('csv:quoteValues', true),
formatFactory,
escapeFormulaValues: false,
}),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,28 +8,28 @@
*/

import React from 'react';
import { merge } from 'rxjs';

import { isOfAggregateQueryType, isOfQueryType } from '@kbn/es-query';
import { createKibanaReactContext } from '@kbn/kibana-react-plugin/public';
import { Action, IncompatibleActionError } from '@kbn/ui-actions-plugin/public';

import {
apiCanAccessViewMode,
apiPublishesPartialUnifiedSearch,
apiHasUniqueId,
CanAccessViewMode,
EmbeddableApiContext,
getInheritedViewMode,
getViewModeSubject,
HasParentApi,
PublishesUnifiedSearch,
HasUniqueId,
PublishesDataViews,
PublishesUnifiedSearch,
apiCanAccessViewMode,
apiHasUniqueId,
apiPublishesPartialUnifiedSearch,
getInheritedViewMode,
getViewModeSubject,
} from '@kbn/presentation-publishing';
import { merge } from 'rxjs';
import { pluginServices } from '../services/plugin_services';
import { FiltersNotificationPopover } from './filters_notification_popover';
import { Action, IncompatibleActionError } from '@kbn/ui-actions-plugin/public';

import { coreServices } from '../services/kibana_services';
import { dashboardFilterNotificationActionStrings } from './_dashboard_actions_strings';
import { FiltersNotificationPopover } from './filters_notification_popover';

export const BADGE_FILTERS_NOTIFICATION = 'ACTION_FILTERS_NOTIFICATION';

Expand Down Expand Up @@ -58,18 +58,12 @@ export class FiltersNotificationAction implements Action<EmbeddableApiContext> {
public readonly type = BADGE_FILTERS_NOTIFICATION;
public readonly order = 2;

private settingsService;

constructor() {
({ settings: this.settingsService } = pluginServices.getServices());
}

public readonly MenuItem = ({ context }: { context: EmbeddableApiContext }) => {
const { embeddable } = context;
if (!isApiCompatible(embeddable)) throw new IncompatibleActionError();

const { Provider: KibanaReactContextProvider } = createKibanaReactContext({
uiSettings: this.settingsService.uiSettings,
uiSettings: coreServices.uiSettings,
});

return (
Expand Down
Loading