Skip to content
1 change: 1 addition & 0 deletions src/platform/plugins/private/links/common/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,4 @@
*/

export { APP_ICON, APP_NAME, CONTENT_ID, DISPLAY_NAME, LATEST_VERSION } from './constants';
export { extractReferences, injectReferences } from './persistable_state';
Original file line number Diff line number Diff line change
Expand Up @@ -67,18 +67,19 @@ export function injectReferences({
}

const { links } = attributes;
links.forEach((link) => {
const newLinks = links.map((link) => {
if (link.type === DASHBOARD_LINK_TYPE && link.destinationRefName) {
const reference = findReference(link.destinationRefName, references);
link.destination = reference.id;
delete link.destinationRefName;
const { destinationRefName, ...rest } = link;
return { ...rest, destination: reference.id };
}
return link;
});

return {
attributes: {
...attributes,
links,
links: newLinks,
},
};
}
15 changes: 15 additions & 0 deletions src/platform/plugins/private/links/common/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,10 @@
*/

import type { SavedObjectsResolveResponse } from '@kbn/core-saved-objects-api-server';
import type { SerializedTitles } from '@kbn/presentation-publishing';
import type { DynamicActionsSerializedState } from '@kbn/embeddable-enhanced-plugin/public/plugin';
import { CONTENT_ID } from './constants';
import { LinksAttributes } from './content_management';

export type LinksContentType = typeof CONTENT_ID;

Expand All @@ -18,3 +21,15 @@ export interface SharingSavedObjectProps {
aliasPurpose?: SavedObjectsResolveResponse['alias_purpose'];
sourceId?: string;
}

export interface LinksByReferenceSerializedState {
savedObjectId: string;
}

export interface LinksByValueSerializedState {
attributes: LinksAttributes;
}

export type LinksSerializedState = SerializedTitles &
Partial<DynamicActionsSerializedState> &
(LinksByReferenceSerializedState | LinksByValueSerializedState);
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
*/

import React, { createContext, useMemo } from 'react';
import { cloneDeep } from 'lodash';
import { BehaviorSubject } from 'rxjs';
import { EuiListGroup, EuiPanel } from '@elastic/eui';

Expand All @@ -29,17 +28,13 @@ import {
} from '../../common/content_management';
import { DashboardLinkComponent } from '../components/dashboard_link/dashboard_link_component';
import { ExternalLinkComponent } from '../components/external_link/external_link_component';
import { LinksApi, LinksParentApi, LinksRuntimeState, ResolvedLink } from '../types';
import { DISPLAY_NAME } from '../../common';
import {
LinksApi,
LinksByReferenceSerializedState,
LinksByValueSerializedState,
LinksParentApi,
LinksRuntimeState,
LinksSerializedState,
ResolvedLink,
} from '../types';
import { DISPLAY_NAME } from '../../common';
import { injectReferences } from '../../common/persistable_state';
} from '../../common/types';

import '../components/links_component.scss';
import { checkForDuplicateTitle, linksClient } from '../content_management';
Expand All @@ -61,8 +56,7 @@ export const getLinksEmbeddableFactory = () => {
> = {
type: CONTENT_ID,
deserializeState: async (serializedState) => {
// Clone the state to avoid an object not extensible error when injecting references
const state = cloneDeep(serializedState.rawState);
const state = serializedState.rawState;
const { title, description, hidePanelTitles } = serializedState.rawState;

if (linksSerializeStateIsByReference(state)) {
Expand All @@ -76,21 +70,16 @@ export const getLinksEmbeddableFactory = () => {
};
}

const { attributes: attributesWithInjectedIds } = injectReferences({
attributes: state.attributes,
references: serializedState.references ?? [],
});

const resolvedLinks = await resolveLinks(attributesWithInjectedIds.links ?? []);
const resolvedLinks = await resolveLinks(state.attributes.links ?? []);

return {
title,
description,
hidePanelTitles,
links: resolvedLinks,
layout: attributesWithInjectedIds.layout,
defaultPanelTitle: attributesWithInjectedIds.title,
defaultPanelDescription: attributesWithInjectedIds.description,
layout: state.attributes.layout,
defaultPanelTitle: state.attributes.title,
defaultPanelDescription: state.attributes.description,
};
},
buildEmbeddable: async (state, buildApi, uuid, parentApi) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,9 @@
import type { SOWithMetadata } from '@kbn/content-management-utils';
import { LinksAttributes } from '../../common/content_management';
import { injectReferences } from '../../common/persistable_state';
import { LinksByReferenceSerializedState, LinksRuntimeState, LinksSerializedState } from '../types';
import { LinksRuntimeState } from '../types';
import { resolveLinks } from './resolve_links';
import { LinksByReferenceSerializedState, LinksSerializedState } from '../../common/types';

export const linksSerializeStateIsByReference = (
state?: LinksSerializedState
Expand Down
16 changes: 2 additions & 14 deletions src/platform/plugins/private/links/public/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,14 @@ import {
SerializedTitles,
} from '@kbn/presentation-publishing';
import { DefaultEmbeddableApi } from '@kbn/embeddable-plugin/public';
import { DynamicActionsSerializedState } from '@kbn/embeddable-enhanced-plugin/public/plugin';
import { HasSerializedChildState, PresentationContainer } from '@kbn/presentation-containers';
import { LocatorPublic } from '@kbn/share-plugin/common';
import { DashboardLocatorParams, DASHBOARD_API_TYPE } from '@kbn/dashboard-plugin/public';
import type { DashboardAttributes } from '@kbn/dashboard-plugin/server';

import { CONTENT_ID } from '../common';
import { Link, LinksAttributes, LinksLayoutType } from '../common/content_management';
import { Link, LinksLayoutType } from '../common/content_management';
import { LinksByReferenceSerializedState, LinksSerializedState } from '../common/types';

export type LinksParentApi = PresentationContainer &
HasType<typeof DASHBOARD_API_TYPE> &
Expand All @@ -42,18 +42,6 @@ export type LinksApi = HasType<typeof CONTENT_ID> &
HasEditCapabilities &
HasLibraryTransforms<LinksByReferenceSerializedState, LinksByValueSerializedState>;

export interface LinksByReferenceSerializedState {
savedObjectId: string;
}

export interface LinksByValueSerializedState {
attributes: LinksAttributes;
}

export type LinksSerializedState = SerializedTitles &
Partial<DynamicActionsSerializedState> &
(LinksByReferenceSerializedState | LinksByValueSerializedState);

export interface LinksRuntimeState
extends Partial<LinksByReferenceSerializedState>,
SerializedTitles {
Expand Down
40 changes: 39 additions & 1 deletion src/platform/plugins/private/links/server/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,15 @@
*/

import { CoreSetup, CoreStart, Logger, Plugin, PluginInitializerContext } from '@kbn/core/server';
import type { EmbeddableSetup } from '@kbn/embeddable-plugin/server';
import type { ContentManagementServerSetup } from '@kbn/content-management-plugin/server';
import { CONTENT_ID, LATEST_VERSION } from '../common';
import { EmbeddableStateWithType } from '@kbn/embeddable-plugin/common';
import { CONTENT_ID, LATEST_VERSION, extractReferences, injectReferences } from '../common';
import { LinksAttributes } from '../common/content_management';
import { LinksStorage } from './content_management';
import { linksSavedObjectType } from './saved_objects';
import { LinksSerializedState } from '../common/types';
import { LinksByValueSerializedState } from '../common/types';

export class LinksServerPlugin implements Plugin<object, object> {
private readonly logger: Logger;
Expand All @@ -25,6 +29,7 @@ export class LinksServerPlugin implements Plugin<object, object> {
core: CoreSetup,
plugins: {
contentManagement: ContentManagementServerSetup;
embeddable: EmbeddableSetup;
}
) {
plugins.contentManagement.register({
Expand All @@ -38,6 +43,39 @@ export class LinksServerPlugin implements Plugin<object, object> {
},
});

plugins.embeddable.registerEmbeddableFactory({
id: CONTENT_ID,
extract: (state) => {
const typedState = state as EmbeddableStateWithType & LinksSerializedState;
if (!('attributes' in typedState) || typedState.attributes === undefined) {
return { state, references: [] };
}

const { attributes, references } = extractReferences({
attributes: typedState.attributes,
} as LinksByValueSerializedState);
return {
state: { ...state, attributes },
references,
};
},
inject: (state, references) => {
const typedState = state as EmbeddableStateWithType & LinksSerializedState;
if (!('attributes' in typedState) || typedState.attributes === undefined) {
return typedState;
}

const { attributes } = injectReferences({
attributes: typedState.attributes,
references,
});
return {
...typedState,
attributes,
};
},
});

core.savedObjects.registerType<LinksAttributes>(linksSavedObjectType);

return {};
Expand Down
1 change: 1 addition & 0 deletions src/platform/plugins/shared/controls/common/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ export const DEFAULT_IGNORE_PARENT_SETTINGS = {
} as const;
export const DEFAULT_AUTO_APPLY_SELECTIONS = true;

export const REFERENCE_NAME_PREFIX = 'controlGroup_';
export const TIME_SLIDER_CONTROL = 'timeSlider';
export const RANGE_SLIDER_CONTROL = 'rangeSliderControl';
export const OPTIONS_LIST_CONTROL = 'optionsListControl';
Expand Down
1 change: 1 addition & 0 deletions src/platform/plugins/shared/controls/common/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ export {
CONTROL_WIDTH_OPTIONS,
CONTROL_CHAINING_OPTIONS,
CONTROL_LABEL_POSITION_OPTIONS,
REFERENCE_NAME_PREFIX,
OPTIONS_LIST_CONTROL,
RANGE_SLIDER_CONTROL,
TIME_SLIDER_CONTROL,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
* License v3.0 only", or the "Server Side Public License, v 1".
*/

const REFERENCE_NAME_PREFIX = 'controlGroup_';
import { REFERENCE_NAME_PREFIX } from '../../../common';

export function getReferenceName(controlId: string, referenceNameSuffix: string) {
return `${REFERENCE_NAME_PREFIX}${controlId}:${referenceNameSuffix}`;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
EmbeddablePersistableStateService,
EmbeddableStateWithType,
} from '@kbn/embeddable-plugin/common';
import { REFERENCE_NAME_PREFIX } from '@kbn/controls-plugin/common';
import { ParsedDashboardAttributesWithType } from '../../types';

export const getReferencesForPanelId = (id: string, references: Reference[]): Reference[] => {
Expand All @@ -24,7 +25,7 @@ export const getReferencesForPanelId = (id: string, references: Reference[]): Re
};

export const getReferencesForControls = (references: Reference[]): Reference[] => {
return references.filter((reference) => reference.name.startsWith(controlGroupReferencePrefix));
return references.filter((reference) => reference.name.startsWith(REFERENCE_NAME_PREFIX));
};

export const prefixReferencesFromPanel = (id: string, references: Reference[]): Reference[] => {
Expand All @@ -37,8 +38,6 @@ export const prefixReferencesFromPanel = (id: string, references: Reference[]):
}));
};

const controlGroupReferencePrefix = 'controlGroup_';

export const createInject = (
persistableStateService: EmbeddablePersistableStateService
): EmbeddablePersistableStateService['inject'] => {
Expand Down
6 changes: 5 additions & 1 deletion src/platform/plugins/shared/dashboard/common/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,11 @@ export {
createExtract,
} from './dashboard_container/persistable_state/dashboard_container_references';

export { prefixReferencesFromPanel } from './dashboard_container/persistable_state/dashboard_container_references';
export {
prefixReferencesFromPanel,
getReferencesForControls,
getReferencesForPanelId,
} from './dashboard_container/persistable_state/dashboard_container_references';

export {
convertPanelsArrayToPanelMap,
Expand Down
Loading