Skip to content
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
4 changes: 2 additions & 2 deletions examples/embeddable_examples/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@
"@kbn/data-plugin",
"@kbn/charts-plugin",
"@kbn/field-formats-plugin",
"@kbn/content-management-utils",
"@kbn/core-lifecycle-browser",
"@kbn/presentation-util-plugin",
"@kbn/unified-field-list",
Expand All @@ -39,6 +38,7 @@
"@kbn/kibana-utils-plugin",
"@kbn/core-mount-utils-browser",
"@kbn/react-kibana-mount",
"@kbn/shared-ux-router"
"@kbn/shared-ux-router",
"@kbn/config-schema"
]
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,15 @@ import { migrateByValueDashboardPanels } from './migrate_by_value_dashboard_pane
import { createExtractPanelReferencesMigration } from './migrate_extract_panel_references';

export interface DashboardSavedObjectTypeMigrationsDeps {
embeddable: EmbeddableSetup;
core: CoreSetup<{ embeddable: EmbeddableStart }>;
embeddableSetup: EmbeddableSetup;
getEmbeddableStart: () => EmbeddableStart | undefined;
}

export const createDashboardSavedObjectTypeMigrations = (
deps: DashboardSavedObjectTypeMigrationsDeps
): SavedObjectMigrationMap => {
const embeddableMigrations = mapValues<MigrateFunctionsObject, SavedObjectMigration>(
deps.embeddable.getAllMigrations(),
deps.embeddableSetup.getAllMigrations(),
migrateByValueDashboardPanels
);

Expand All @@ -40,7 +40,7 @@ export const createDashboardSavedObjectTypeMigrations = (
'7.0.0': flow(migrations700),
'7.3.0': flow(migrations730),
'7.9.3': flow(migrateMatchAllQuery),
'7.11.0': flow(createExtractPanelReferencesMigration(deps)),
'7.11.0': createExtractPanelReferencesMigration(deps),
'7.14.0': flow(replaceIndexPatternReference),
'7.17.3': flow(migrateExplicitlyHiddenTitles),
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@
* License v3.0 only", or the "Server Side Public License, v 1".
*/

import { inspect } from 'util';
import { SavedObject, SavedObjectMigrationParams } from '@kbn/core-saved-objects-server';
import { EmbeddableStart } from '@kbn/embeddable-plugin/server';
import type { DashboardSavedObjectTypeMigrationsDeps } from './dashboard_saved_object_migrations';
import type { DashboardSavedObjectAttributes } from '../schema';
import type { DashboardSavedObjectTypeMigrationsDeps } from './dashboard_saved_object_migrations';
import { itemToSavedObject, savedObjectToItem } from '../../content_management/latest';

/**
Expand All @@ -22,26 +22,36 @@ import { itemToSavedObject, savedObjectToItem } from '../../content_management/l
* 1. In addition to regular `panel_` we will get new references which are extracted by `embeddablePersistableStateService` (dashboard drilldown references)
* 2. `panel_` references will be regenerated
* All other references like index-patterns are forwarded non touched
* @param deps
*
* This migration uses the deferred flag on {@link SavedObjectMigrationParams | SavedObjectMigrationParams} which means the
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice, this is a way cleaner solution.

* migration only runs when the saved object is accessed. This ensures that the embeddable service is available and can be
* used to extract the references correctly.
*/
export function createExtractPanelReferencesMigration(
deps: DashboardSavedObjectTypeMigrationsDeps
): SavedObjectMigrationParams<DashboardSavedObjectAttributes> {
let embeddableStart: EmbeddableStart;
void deps.core.getStartServices().then(([_, { embeddable }]) => {
embeddableStart = embeddable;
});
return {
deferred: true,
transform: (doc) => {
transform: (doc, { log }) => {
const references = doc.references ?? [];

const getExceptionMessage = (error: Error) =>
`Exception @ createExtractPanelReferencesMigration while trying to extract dashboard panels!\n` +
`${error.stack}\n` +
`dashboard: ${inspect(doc, false, null)}`;
/**
* Remembering this because dashboard's extractReferences won't return those
* All other references like `panel_` will be overwritten
*/
const oldNonPanelReferences = references.filter((ref) => !ref.name.startsWith('panel_'));

const embeddableStart = deps.getEmbeddableStart();
if (!embeddableStart) {
log.warn(
`Exception @ createExtractPanelReferencesMigration!\nEmbeddable start service is not available.`
);
return doc;
}

// Content Management transform functions `savedObjectToItem` and `itemToSavedObject`
// will run embeddable inject and extract functions for each panel
const { item, error: itemError } = savedObjectToItem(
Expand All @@ -50,14 +60,20 @@ export function createExtractPanelReferencesMigration(
false
);

if (itemError) throw itemError;
if (itemError) {
log.warn(getExceptionMessage(itemError));
return doc;
}

const {
attributes,
error: attributesError,
references: newPanelReferences,
} = itemToSavedObject({ attributes: item.attributes, embeddable: embeddableStart });
if (attributesError) throw attributesError;
if (attributesError) {
log.warn(getExceptionMessage(attributesError));
return doc;
}

return {
...doc,
Expand Down
49 changes: 20 additions & 29 deletions src/platform/plugins/shared/dashboard/server/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,11 @@
* License v3.0 only", or the "Server Side Public License, v 1".
*/

import {
TaskManagerSetupContract,
TaskManagerStartContract,
} from '@kbn/task-manager-plugin/server';
import { EmbeddableSetup, EmbeddableStart } from '@kbn/embeddable-plugin/server';
import { UsageCollectionSetup, UsageCollectionStart } from '@kbn/usage-collection-plugin/server';
import { ContentManagementServerSetup } from '@kbn/content-management-plugin/server';
import { SharePluginStart } from '@kbn/share-plugin/server';
import { PluginInitializerContext, CoreSetup, CoreStart, Plugin, Logger } from '@kbn/core/server';
import { registerContentInsights } from '@kbn/content-management-content-insights-server';

import type { SavedObjectTaggingStart } from '@kbn/saved-objects-tagging-plugin/server';
import { EmbeddableStart } from '@kbn/embeddable-plugin/server';
import {
initializeDashboardTelemetryTask,
scheduleDashboardTelemetry,
Expand All @@ -27,47 +20,42 @@ import {
import { getUISettings } from './ui_settings';
import { DashboardStorage } from './content_management';
import { capabilitiesProvider } from './capabilities_provider';
import { DashboardPluginSetup, DashboardPluginStart } from './types';
import {
DashboardPluginSetup,
DashboardPluginStart,
DashboardSetupDeps,
DashboardStartDeps,
} from './types';
import { createDashboardSavedObjectType } from './dashboard_saved_object';
import { CONTENT_ID, LATEST_VERSION } from '../common/content_management';
import { registerDashboardUsageCollector } from './usage/register_collector';
import { dashboardPersistableStateServiceFactory } from './dashboard_container/dashboard_container_embeddable_factory';
import { registerAPIRoutes } from './api';
import { DashboardAppLocatorDefinition } from '../common/locator/locator';

interface SetupDeps {
embeddable: EmbeddableSetup;
usageCollection?: UsageCollectionSetup;
taskManager: TaskManagerSetupContract;
contentManagement: ContentManagementServerSetup;
}

interface StartDeps {
embeddable: EmbeddableStart;
taskManager: TaskManagerStartContract;
usageCollection?: UsageCollectionStart;
savedObjectsTagging?: SavedObjectTaggingStart;
share?: SharePluginStart;
}

export class DashboardPlugin
implements Plugin<DashboardPluginSetup, DashboardPluginStart, SetupDeps, StartDeps>
implements
Plugin<DashboardPluginSetup, DashboardPluginStart, DashboardSetupDeps, DashboardStartDeps>
{
private contentClient?: ReturnType<ContentManagementServerSetup['register']>['contentClient'];
private embeddableService?: EmbeddableStart;
private readonly logger: Logger;

constructor(private initializerContext: PluginInitializerContext) {
this.logger = initializerContext.logger.get();
}

public setup(core: CoreSetup<StartDeps, DashboardPluginStart>, plugins: SetupDeps) {
public setup(
core: CoreSetup<DashboardStartDeps, DashboardPluginStart>,
plugins: DashboardSetupDeps
) {
this.logger.debug('dashboard: Setup');

core.savedObjects.registerType(
createDashboardSavedObjectType({
migrationDeps: {
core,
embeddable: plugins.embeddable,
embeddableSetup: plugins.embeddable,
getEmbeddableStart: () => this.embeddableService,
},
})
);
Expand Down Expand Up @@ -136,8 +124,11 @@ export class DashboardPlugin
return {};
}

public start(core: CoreStart, plugins: StartDeps) {
public start(core: CoreStart, plugins: DashboardStartDeps) {
this.logger.debug('dashboard: Started');
if (plugins.embeddable) {
this.embeddableService = plugins.embeddable;
}

if (plugins.share) {
plugins.share.url.locators.create(
Expand Down
23 changes: 23 additions & 0 deletions src/platform/plugins/shared/dashboard/server/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,29 @@
*/

import { ContentManagementServerSetup } from '@kbn/content-management-plugin/server';
import { EmbeddableSetup, EmbeddableStart } from '@kbn/embeddable-plugin/server';
import { SavedObjectTaggingStart } from '@kbn/saved-objects-tagging-plugin/server';
import { SharePluginStart } from '@kbn/share-plugin/server';
import {
TaskManagerSetupContract,
TaskManagerStartContract,
} from '@kbn/task-manager-plugin/server';
import { UsageCollectionSetup, UsageCollectionStart } from '@kbn/usage-collection-plugin/server';

export interface DashboardSetupDeps {
embeddable: EmbeddableSetup;
usageCollection?: UsageCollectionSetup;
taskManager: TaskManagerSetupContract;
contentManagement: ContentManagementServerSetup;
}

export interface DashboardStartDeps {
embeddable: EmbeddableStart;
taskManager: TaskManagerStartContract;
usageCollection?: UsageCollectionStart;
savedObjectsTagging?: SavedObjectTaggingStart;
share?: SharePluginStart;
}

// eslint-disable-next-line @typescript-eslint/no-empty-interface
export interface DashboardPluginSetup {}
Expand Down
1 change: 1 addition & 0 deletions src/platform/plugins/shared/embeddable/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
"@kbn/react-kibana-mount",
"@kbn/analytics",
"@kbn/ui-theme",
"@kbn/config-schema",
],
"exclude": ["target/**/*"]
}