Skip to content

Commit

Permalink
decouple url drilldown action from Embeddable framework (elastic#175930)
Browse files Browse the repository at this point in the history
Part of elastic#175138 and prerequisite
for elastic#174960

PR decouples Url drilldown action from Embeddable framework by migrating
to sets of composable interfaces.

### test instructions
1. Create panel and add "Url drilldown"
2. Verify `context` variables are populated with the same values when
they were grabbed from embeddable.input and embeddable.output
<img width="600" alt="Screenshot 2024-01-31 at 2 11 20 PM"
src="https://github.com/elastic/kibana/assets/373691/150f7a61-911f-4fb6-bf85-5c0481865e4b">

---------

Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
  • Loading branch information
2 people authored and fkanout committed Mar 4, 2024
1 parent f57c51f commit 285ea9b
Show file tree
Hide file tree
Showing 20 changed files with 230 additions and 386 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
*/

import { i18n } from '@kbn/i18n';
import type { EmbeddableApiContext } from '@kbn/presentation-publishing';
import type { Datatable } from '@kbn/expressions-plugin/common';
import { Trigger } from '.';

Expand All @@ -22,10 +23,7 @@ export const rowClickTrigger: Trigger = {
}),
};

export interface RowClickContext {
// Need to make this unknown to prevent circular dependencies.
// Apps using this property will need to cast to `IEmbeddable`.
embeddable?: unknown;
export type RowClickContext = Partial<EmbeddableApiContext> & {
data: {
/**
* Row index, starting from 0, where user clicked.
Expand All @@ -40,4 +38,4 @@ export interface RowClickContext {
*/
columns?: string[];
};
}
};
1 change: 1 addition & 0 deletions packages/kbn-ui-actions-browser/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,6 @@
"kbn_references": [
"@kbn/i18n",
"@kbn/expressions-plugin",
"@kbn/presentation-publishing",
]
}
Original file line number Diff line number Diff line change
Expand Up @@ -686,4 +686,12 @@ export class DashboardContainer
}
if (resetChangedPanelCount) this.reactEmbeddableChildren.next(currentChildren);
};

public getFilters() {
return this.getInput().filters;
}

public getQuery(): Query | undefined {
return this.getInput().query;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,14 @@ import { i18n } from '@kbn/i18n';
import { PhaseEvent, PhaseEventType } from '@kbn/presentation-publishing';
import deepEqual from 'fast-deep-equal';
import { isNil } from 'lodash';
import { BehaviorSubject, map, Subscription, distinct } from 'rxjs';
import {
BehaviorSubject,
map,
Subscription,
distinct,
combineLatest,
distinctUntilChanged,
} from 'rxjs';
import { embeddableStart } from '../../../kibana_services';
import { isFilterableEmbeddable } from '../../filterable_embeddable';
import {
Expand All @@ -31,7 +38,7 @@ import {
import { canLinkLegacyEmbeddable, linkLegacyEmbeddable } from './link_legacy_embeddable';
import { canUnlinkLegacyEmbeddable, unlinkLegacyEmbeddable } from './unlink_legacy_embeddable';

export type CommonLegacyInput = EmbeddableInput & { timeRange: TimeRange };
export type CommonLegacyInput = EmbeddableInput & { savedObjectId?: string; timeRange: TimeRange };
export type CommonLegacyOutput = EmbeddableOutput & { indexPatterns: DataView[] };
export type CommonLegacyEmbeddable = IEmbeddable<CommonLegacyInput, CommonLegacyOutput>;

Expand Down Expand Up @@ -135,6 +142,25 @@ export const legacyEmbeddableToApi = (
const defaultPanelTitle = outputKeyToSubject<string>('defaultTitle');
const disabledActionIds = inputKeyToSubject<string[] | undefined>('disabledActions');

function getSavedObjectId(input: { savedObjectId?: string }, output: { savedObjectId?: string }) {
return output.savedObjectId ?? input.savedObjectId;
}
const savedObjectId = new BehaviorSubject<string | undefined>(
getSavedObjectId(embeddable.getInput(), embeddable.getOutput())
);
subscriptions.add(
combineLatest([embeddable.getInput$(), embeddable.getOutput$()])
.pipe(
map(([input, output]) => {
return getSavedObjectId(input, output);
}),
distinctUntilChanged()
)
.subscribe((nextSavedObjectId) => {
savedObjectId.next(nextSavedObjectId);
})
);

const blockingError = new BehaviorSubject<ErrorLike | undefined>(undefined);
subscriptions.add(
embeddable.getOutput$().subscribe({
Expand Down Expand Up @@ -238,6 +264,8 @@ export const legacyEmbeddableToApi = (

canUnlinkFromLibrary: () => canUnlinkLegacyEmbeddable(embeddable),
unlinkFromLibrary: () => unlinkLegacyEmbeddable(embeddable),

savedObjectId,
},
destroyAPI: () => {
subscriptions.unsubscribe();
Expand Down
2 changes: 2 additions & 0 deletions src/plugins/embeddable/public/lib/embeddables/embeddable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,7 @@ export abstract class Embeddable<
getFallbackTimeRange: this.getFallbackTimeRange,
canUnlinkFromLibrary: this.canUnlinkFromLibrary,
isCompatibleWithLocalUnifiedSearch: this.isCompatibleWithLocalUnifiedSearch,
savedObjectId: this.savedObjectId,
} = api);

setTimeout(() => {
Expand Down Expand Up @@ -186,6 +187,7 @@ export abstract class Embeddable<
public canUnlinkFromLibrary: LegacyEmbeddableAPI['canUnlinkFromLibrary'];
public getFallbackTimeRange: LegacyEmbeddableAPI['getFallbackTimeRange'];
public isCompatibleWithLocalUnifiedSearch: LegacyEmbeddableAPI['isCompatibleWithLocalUnifiedSearch'];
public savedObjectId: LegacyEmbeddableAPI['savedObjectId'];

public getEditHref(): string | undefined {
return this.getOutput().editUrl ?? undefined;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import {
PublishesWritablePanelDescription,
PublishesWritablePanelTitle,
PublishesPhaseEvents,
PublishesSavedObjectId,
} from '@kbn/presentation-publishing';
import { Observable } from 'rxjs';
import { EmbeddableInput } from '../../../common/types';
Expand Down Expand Up @@ -54,7 +55,8 @@ export type LegacyEmbeddableAPI = HasType &
PublishesWritablePanelDescription &
Partial<CanLinkToLibrary & CanUnlinkFromLibrary> &
HasParentApi<DefaultPresentationPanelApi['parentApi']> &
EmbeddableHasTimeRange;
EmbeddableHasTimeRange &
PublishesSavedObjectId;

export interface EmbeddableAppContext {
/**
Expand Down
29 changes: 13 additions & 16 deletions src/plugins/embeddable/public/lib/triggers/triggers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
*/

import { i18n } from '@kbn/i18n';
import type { EmbeddableApiContext } from '@kbn/presentation-publishing';
import { Datatable, DatatableColumnMeta } from '@kbn/expressions-plugin/common';
import { Trigger, RowClickContext } from '@kbn/ui-actions-plugin/public';
import { BooleanRelation } from '@kbn/es-query';
Expand All @@ -16,8 +17,7 @@ export interface EmbeddableContext<T extends IEmbeddable = IEmbeddable> {
embeddable: T;
}

export interface ValueClickContext<T extends IEmbeddable = IEmbeddable> {
embeddable?: T;
export type ValueClickContext = Partial<EmbeddableApiContext> & {
data: {
data: Array<{
table: Pick<Datatable, 'rows' | 'columns'>;
Expand All @@ -28,10 +28,9 @@ export interface ValueClickContext<T extends IEmbeddable = IEmbeddable> {
timeFieldName?: string;
negate?: boolean;
};
}
};

export interface MultiValueClickContext<T extends IEmbeddable = IEmbeddable> {
embeddable?: T;
export type MultiValueClickContext = Partial<EmbeddableApiContext> & {
data: {
data: Array<{
table: Pick<Datatable, 'rows' | 'columns'>;
Expand All @@ -44,31 +43,29 @@ export interface MultiValueClickContext<T extends IEmbeddable = IEmbeddable> {
timeFieldName?: string;
negate?: boolean;
};
}
};

export interface CellValueContext<T extends IEmbeddable = IEmbeddable> {
embeddable: T;
export type CellValueContext = Partial<EmbeddableApiContext> & {
data: Array<{
value?: any;
eventId?: string;
columnMeta?: DatatableColumnMeta;
}>;
}
};

export interface RangeSelectContext<T extends IEmbeddable = IEmbeddable> {
embeddable?: T;
export type RangeSelectContext = Partial<EmbeddableApiContext> & {
data: {
table: Datatable;
column: number;
range: number[];
timeFieldName?: string;
};
}
};

export type ChartActionContext<T extends IEmbeddable = IEmbeddable> =
| ValueClickContext<T>
| MultiValueClickContext<T>
| RangeSelectContext<T>
export type ChartActionContext =
| ValueClickContext
| MultiValueClickContext
| RangeSelectContext
| RowClickContext;

export const CONTEXT_MENU_TRIGGER = 'CONTEXT_MENU_TRIGGER';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,18 +11,11 @@ import { UiActionsEnhancedDrilldownDefinition as Drilldown } from '@kbn/ui-actio
import { APPLY_FILTER_TRIGGER } from '@kbn/data-plugin/public';
import { ApplyGlobalFilterActionContext } from '@kbn/unified-search-plugin/public';
import { StartDependencies as Start } from '../../plugin';
import { ActionContext, Config, CollectConfigProps } from './types';
import type { ActionApi, ActionContext, Config, CollectConfigProps } from './types';
import { CollectConfigContainer } from './collect_config_container';
import { SAMPLE_DASHBOARD_TO_DISCOVER_DRILLDOWN } from './constants';
import { txtGoToDiscover } from './i18n';

const isOutputWithIndexPatterns = (
output: unknown
): output is { indexPatterns: Array<{ id: string }> } => {
if (!output || typeof output !== 'object') return false;
return Array.isArray((output as any).indexPatterns);
};

export interface Params {
start: StartServicesGetter<Pick<Start, 'data' | 'discover'>>;
}
Expand Down Expand Up @@ -67,10 +60,10 @@ export class DashboardToDiscoverDrilldown
let indexPatternId =
!!config.customIndexPattern && !!config.indexPatternId ? config.indexPatternId : '';

if (!indexPatternId && !!context.embeddable) {
const output = context.embeddable!.getOutput();
if (isOutputWithIndexPatterns(output) && output.indexPatterns.length > 0) {
indexPatternId = output.indexPatterns[0].id;
if (!indexPatternId) {
const dataViews = (context?.embeddable as ActionApi).dataViews?.value;
if (dataViews?.[0].id) {
indexPatternId = dataViews[0].id;
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,13 @@
* 2.0.
*/

import type { PublishesDataViews } from '@kbn/presentation-publishing';
import { CollectConfigProps as CollectConfigPropsBase } from '@kbn/kibana-utils-plugin/public';
import { ApplyGlobalFilterActionContext } from '@kbn/unified-search-plugin/public';
import { IEmbeddable } from '@kbn/embeddable-plugin/public';

export type ActionContext = ApplyGlobalFilterActionContext & { embeddable: IEmbeddable };
export type ActionApi = Partial<PublishesDataViews>;

export type ActionContext = ApplyGlobalFilterActionContext & { embeddable: ActionApi };

export type Config = {
/**
Expand Down
1 change: 1 addition & 0 deletions x-pack/examples/ui_actions_enhanced_examples/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,5 +29,6 @@
"@kbn/i18n",
"@kbn/unified-search-plugin",
"@kbn/utility-types",
"@kbn/presentation-publishing",
]
}
20 changes: 0 additions & 20 deletions x-pack/plugins/drilldowns/url_drilldown/public/lib/test/data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@
*/

import { DatatableColumnType } from '@kbn/expressions-plugin/common';
import type { Query, Filter, TimeRange } from '@kbn/es-query';
import { Embeddable, EmbeddableInput, EmbeddableOutput } from '@kbn/embeddable-plugin/public';

export const createPoint = ({
field,
Expand Down Expand Up @@ -154,21 +152,3 @@ export const rowClickData = {
'e0719f1a-04fb-4036-a63c-c25deac3f011',
],
};

interface TestInput extends EmbeddableInput {
savedObjectId?: string;
query?: Query;
filters?: Filter[];
timeRange?: TimeRange;
}

interface TestOutput extends EmbeddableOutput {
indexPatterns?: Array<{ id: string }>;
}

export class TestEmbeddable extends Embeddable<TestInput, TestOutput> {
type = 'test';

destroy() {}
reload() {}
}
Loading

0 comments on commit 285ea9b

Please sign in to comment.