Skip to content

Commit 1c53cd3

Browse files
nickofthymedej611kibanamachine
authored
[Lens] move reference handling to server (#239029)
## Summary Move Lens `reference` handling to server side. Close #221943 ## Details Lens no longer relies on `references` from the `buildEmbeddable`. We now inject/extract references on the server. Lens duplicates `references` in it's own serialized state so we just move them there and add the `savedObjectId` for by-ref Lens panels. Lens still inject these `references` internally by type across the Lens code. For now we still store the `references` duplicated in the Lens SO state, but we can clean this up when we extract all the internal reference handling. ### Checklist - [x] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios - [x] Review the [backport guidelines](https://docs.google.com/document/d/1VyN5k91e5OVumlc0Gb9RPa3h1ewuPE705nRtioPiTvY/edit?usp=sharing) and apply applicable `backport:*` labels. --------- Co-authored-by: Marco Liberati <[email protected]> Co-authored-by: dej611 <[email protected]> Co-authored-by: kibanamachine <[email protected]>
1 parent b622962 commit 1c53cd3

File tree

48 files changed

+852
-690
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

48 files changed

+852
-690
lines changed

src/platform/packages/shared/kbn-lens-common/embeddable/types.ts

Lines changed: 53 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@
77
* License v3.0 only", or the "Server Side Public License, v 1".
88
*/
99

10+
import type { BehaviorSubject } from 'rxjs';
11+
12+
import type { HasSerializedChildState } from '@kbn/presentation-containers';
1013
import type {
1114
AggregateQuery,
1215
ExecutionContextSearch,
@@ -44,6 +47,7 @@ import type {
4447
PublishingSubject,
4548
SerializedTitles,
4649
ViewMode,
50+
useSearchApi,
4751
} from '@kbn/presentation-publishing';
4852
import type { Action } from '@kbn/ui-actions-plugin/public';
4953
import type {
@@ -126,9 +130,9 @@ export interface PreventableEvent {
126130
preventDefault(): void;
127131
}
128132

129-
interface LensByValue {
130-
// by-value
131-
attributes?: Simplify<LensSavedObjectAttributes>;
133+
export interface LensByValueBase {
134+
savedObjectId?: string; // really should be never but creates type issues
135+
attributes?: LensSavedObjectAttributes;
132136
}
133137

134138
export interface LensOverrides {
@@ -150,20 +154,22 @@ export interface LensOverrides {
150154
/**
151155
* Lens embeddable props broken down by type
152156
*/
153-
154-
export interface LensByReference {
155-
// by-reference
157+
interface LensByReferenceBase {
156158
savedObjectId?: string;
159+
attributes?: never;
157160
}
158161

159162
interface ContentManagementProps {
160163
sharingSavedObjectProps?: SharingSavedObjectProps;
161164
managed?: boolean;
162165
}
163166

164-
export type LensPropsVariants = (LensByValue & LensByReference) & {
167+
interface LensWithReferences {
168+
/**
169+
* @deprecated use `state.attributes.references`
170+
*/
165171
references?: Reference[];
166-
};
172+
}
167173

168174
export interface ViewInDiscoverCallbacks extends LensApiProps {
169175
canViewUnderlyingData$: PublishingSubject<boolean>;
@@ -259,16 +265,29 @@ interface LensRequestHandlersProps {
259265
* * Panel settings
260266
* * other props from the embeddable
261267
*/
262-
export type LensSerializedState = Simplify<
263-
LensPropsVariants &
264-
LensOverrides &
268+
type LensSerializedSharedState = Simplify<
269+
LensOverrides &
270+
LensWithReferences &
265271
LensUnifiedSearchContext &
266272
LensPanelProps &
267273
SerializedTitles &
268274
Omit<LensSharedProps, 'noPadding'> &
269275
Partial<DynamicActionsSerializedState> & { isNewPanel?: boolean }
270276
>;
271277

278+
export type LensByValueSerializedState = Simplify<LensSerializedSharedState & LensByValueBase>;
279+
export type LensByRefSerializedState = Simplify<LensSerializedSharedState & LensByReferenceBase>;
280+
281+
/**
282+
* Combined properties of serialized state stored on dashboard panel
283+
*
284+
* Includes:
285+
* - Lens document state (for by-value)
286+
* - Panel settings
287+
* - other props from the embeddable
288+
*/
289+
export type LensSerializedState = LensByRefSerializedState | LensByValueSerializedState;
290+
272291
/**
273292
* Custom props exposed on the Lens exported component
274293
*/
@@ -516,3 +535,26 @@ export interface ESQLVariablesCompatibleDashboardApi {
516535
controlGroupApi$: PublishingSubject<Partial<CanAddNewPanel> | undefined>;
517536
children$: PublishingSubject<{ [key: string]: unknown }>;
518537
}
538+
539+
type SearchApi = ReturnType<typeof useSearchApi>;
540+
541+
interface GeneralLensApi {
542+
searchSessionId$: BehaviorSubject<string | undefined>;
543+
disabledActionIds$: BehaviorSubject<string[] | undefined>;
544+
setDisabledActionIds: (ids: string[] | undefined) => void;
545+
viewMode$: BehaviorSubject<ViewMode | undefined>;
546+
settings: {
547+
syncColors$: BehaviorSubject<boolean>;
548+
syncCursor$: BehaviorSubject<boolean>;
549+
syncTooltips$: BehaviorSubject<boolean>;
550+
};
551+
forceDSL?: boolean;
552+
esqlVariables$: BehaviorSubject<ESQLControlVariable[] | undefined>;
553+
hideTitle$: BehaviorSubject<boolean | undefined>;
554+
reload$: BehaviorSubject<void>;
555+
}
556+
557+
export type LensParentApi = SearchApi &
558+
LensRuntimeState &
559+
GeneralLensApi &
560+
HasSerializedChildState<LensSerializedState>;

src/platform/packages/shared/kbn-lens-common/index.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -252,8 +252,8 @@ export type {
252252
DocumentToExpressionReturnType,
253253
PreventableEvent,
254254
LensOverrides,
255-
LensByReference,
256-
LensPropsVariants,
255+
LensByValueSerializedState,
256+
LensByRefSerializedState,
257257
ViewInDiscoverCallbacks,
258258
IntegrationCallbacks,
259259
LensPublicCallbacks,
@@ -268,6 +268,7 @@ export type {
268268
LensHasEditPanel,
269269
LensInspectorAdapters,
270270
LensApi,
271+
LensParentApi,
271272
LensInternalApi,
272273
ExpressionWrapperProps,
273274
GetStateType,
@@ -276,6 +277,7 @@ export type {
276277
TypedLensSerializedState,
277278
LensEmbeddableOutput,
278279
ESQLVariablesCompatibleDashboardApi,
280+
LensByValueBase,
279281
} from './embeddable/types';
280282
export type {
281283
LensAppLocatorParams,

src/platform/packages/shared/kbn-lens-common/types.ts

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -79,11 +79,7 @@ import type { InspectorOptions } from '@kbn/inspector-plugin/public';
7979
import type { OnSaveProps } from '@kbn/saved-objects-plugin/public';
8080
import type { NavigateToLensContext } from './convert_to_lens_types';
8181
import type { LensAppLocator, MainHistoryLocationState } from './locator_types';
82-
import type {
83-
LensRuntimeState,
84-
LensSavedObjectAttributes,
85-
StructuredDatasourceStates,
86-
} from './embeddable/types';
82+
import type { LensSavedObjectAttributes, StructuredDatasourceStates } from './embeddable/types';
8783
import type {
8884
DimensionLink,
8985
LensConfiguration,
@@ -144,14 +140,6 @@ export interface LensAttributesService {
144140
savedObjectId?: string
145141
) => Promise<string>;
146142
checkForDuplicateTitle: (props: CheckDuplicateTitleProps) => Promise<{ isDuplicate: boolean }>;
147-
injectReferences: (
148-
runtimeState: LensRuntimeState,
149-
references: Reference[] | undefined
150-
) => LensRuntimeState;
151-
extractReferences: (runtimeState: LensRuntimeState) => {
152-
rawState: LensRuntimeState;
153-
references: Reference[];
154-
};
155143
}
156144

157145
export interface LensAppServices extends StartServices {

src/platform/packages/shared/kbn-lens-embeddable-utils/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,6 @@
33
"private": true,
44
"version": "1.0.0",
55
"license": "Elastic License 2.0 OR AGPL-3.0-only OR SSPL-1.0",
6-
"homepage": "https://docs.elastic.dev/kibana-dev-docs/lens/config-builder"
6+
"homepage": "https://docs.elastic.dev/kibana-dev-docs/lens/config-builder",
7+
"sideEffects": false
78
}

x-pack/platform/plugins/shared/cases/server/common/utils.ts

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import type {
1515
import { flatMap, uniqWith, xorWith } from 'lodash';
1616
import type { LensServerPluginSetup } from '@kbn/lens-plugin/server';
1717
import { addSpaceIdToPath } from '@kbn/spaces-plugin/common';
18+
import type { LensEmbeddableStateWithType } from '@kbn/lens-plugin/server/embeddable/types';
1819
import type {
1920
ActionsAttachmentPayload,
2021
AlertAttachmentPayload,
@@ -402,15 +403,16 @@ export const extractLensReferencesFromCommentString = (
402403
lensEmbeddableFactory: LensServerPluginSetup['lensEmbeddableFactory'],
403404
comment: string
404405
): SavedObjectReference[] => {
405-
const extract = lensEmbeddableFactory()?.extract;
406+
const extract = lensEmbeddableFactory().extract;
406407

407408
if (extract) {
408409
const parsedComment = parseCommentString(comment);
409410
const lensVisualizations = getLensVisualizations(parsedComment.children);
410-
const flattenRefs = flatMap(
411-
lensVisualizations,
412-
(lensObject) => extract(lensObject)?.references ?? []
413-
);
411+
const flattenRefs = flatMap(lensVisualizations, (vis) => {
412+
// TODO: Improve these types
413+
const lensVis = vis as unknown as LensEmbeddableStateWithType;
414+
return extract(lensVis).references;
415+
});
414416

415417
const uniqRefs = uniqWith(
416418
flattenRefs,

x-pack/platform/plugins/shared/lens/common/embeddable_factory/index.ts

Lines changed: 0 additions & 58 deletions
This file was deleted.
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/*
2+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3+
* or more contributor license agreements. Licensed under the Elastic License
4+
* 2.0; you may not use this file except in compliance with the Elastic License
5+
* 2.0.
6+
*/
7+
8+
import { cloneDeep, uniqBy } from 'lodash';
9+
10+
import type { Reference } from '@kbn/content-management-utils';
11+
12+
import type { LensSerializedState } from '../../public';
13+
14+
export const injectLensReferences = (
15+
state: LensSerializedState,
16+
references: Reference[] = []
17+
): LensSerializedState => {
18+
const clonedState = cloneDeep(state);
19+
20+
if (clonedState.savedObjectId || !clonedState.attributes) {
21+
return clonedState;
22+
}
23+
24+
// TODO: find a way to cull erroneous dashboard references
25+
const combinedReferences = uniqBy([...references, ...clonedState.attributes.references], 'name');
26+
27+
clonedState.attributes.references = combinedReferences;
28+
29+
return clonedState;
30+
};
31+
32+
export const extractLensReferences = (
33+
state: LensSerializedState
34+
): {
35+
state: LensSerializedState;
36+
references: Reference[];
37+
} => {
38+
return {
39+
state,
40+
references: state.attributes?.references ?? state.references ?? [],
41+
};
42+
};

x-pack/platform/plugins/shared/lens/common/transforms/config_builder_stub.ts

Lines changed: 0 additions & 38 deletions
This file was deleted.

x-pack/platform/plugins/shared/lens/common/transforms/index.ts

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,21 @@
55
* 2.0.
66
*/
77

8-
export { ConfigBuilderStub } from './config_builder_stub';
8+
import type { EnhancementsRegistry } from '@kbn/embeddable-plugin/common/enhancements/registry';
9+
10+
import type { LensTransforms } from './types';
11+
import { getTransformIn } from './transform_in';
12+
import { getTransformOut } from './transform_out';
13+
14+
export interface LensTransformDependencies {
15+
transformEnhancementsIn?: EnhancementsRegistry['transformIn'];
16+
transformEnhancementsOut?: EnhancementsRegistry['transformOut'];
17+
}
18+
19+
export function getLensTransforms(deps: LensTransformDependencies): LensTransforms {
20+
return {
21+
transformIn: getTransformIn(deps),
22+
transformOut: getTransformOut(deps),
23+
transformOutInjectsReferences: true,
24+
};
25+
}

0 commit comments

Comments
 (0)