Skip to content

Commit

Permalink
[Lens] Enables right clicks to the discover drilldown (#136088)
Browse files Browse the repository at this point in the history
* Adds href to the discover drilldown

* Add href function to the Discover action

* Apply nit

Co-authored-by: Joe Reuter <[email protected]>
  • Loading branch information
stratoula and flash1293 authored Jul 12, 2022
1 parent 754fdea commit 2de673f
Show file tree
Hide file tree
Showing 5 changed files with 101 additions and 17 deletions.
2 changes: 1 addition & 1 deletion x-pack/plugins/lens/public/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -294,13 +294,13 @@ export class LensPlugin {
}

visualizations.registerAlias(getLensAliasConfig());

if (discover) {
uiActionsEnhanced.registerDrilldown(
new OpenInDiscoverDrilldown({
discover,
dataViews: () => this.dataViewsService!,
hasDiscoverAccess: () => this.hasDiscoverAccess,
application: () => startServices().core.application,
})
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { createAction } from '@kbn/ui-actions-plugin/public';
import type { DiscoverStart } from '@kbn/discover-plugin/public';
import { IEmbeddable } from '@kbn/embeddable-plugin/public';
import { DataViewsService } from '@kbn/data-views-plugin/public';
import { execute, isCompatible } from './open_in_discover_helpers';
import { execute, isCompatible, getHref } from './open_in_discover_helpers';

const ACTION_OPEN_IN_DISCOVER = 'ACTION_OPEN_IN_DISCOVER';

Expand All @@ -32,6 +32,14 @@ export const createOpenInDiscoverAction = (
i18n.translate('xpack.lens.app.exploreDataInDiscover', {
defaultMessage: 'Explore data in Discover',
}),
getHref: async (context: Context) => {
return getHref({
discover,
dataViews,
hasDiscoverAccess,
...context,
});
},
isCompatible: async (context: Context) => {
return isCompatible({
hasDiscoverAccess,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@
import React, { FormEvent } from 'react';
import { IEmbeddable, EmbeddableInput } from '@kbn/embeddable-plugin/public';
import { DiscoverSetup } from '@kbn/discover-plugin/public';
import { execute, isCompatible } from './open_in_discover_helpers';
import type { ApplicationStart } from '@kbn/core/public';
import { getHref, isCompatible } from './open_in_discover_helpers';
import { mount } from 'enzyme';
import { Filter } from '@kbn/es-query';
import {
Expand All @@ -20,7 +21,7 @@ import { DataViewsService } from '@kbn/data-views-plugin/public';

jest.mock('./open_in_discover_helpers', () => ({
isCompatible: jest.fn(() => true),
execute: jest.fn(),
getHref: jest.fn(),
}));

describe('open in discover drilldown', () => {
Expand All @@ -30,6 +31,7 @@ describe('open in discover drilldown', () => {
discover: {} as DiscoverSetup,
dataViews: () => ({} as DataViewsService),
hasDiscoverAccess: () => true,
application: () => ({} as ApplicationStart),
});
});
it('provides UI to edit config', () => {
Expand All @@ -54,14 +56,12 @@ describe('open in discover drilldown', () => {
);
expect(isCompatible).toHaveBeenCalledWith(expect.objectContaining({ filters }));
});
it('calls through to execute helper', async () => {
it('calls through to getHref helper', async () => {
const filters: Filter[] = [{ meta: { disabled: false } }];
await drilldown.execute(
{ openInNewTab: true },
{ embeddable: { type: 'lens' } as IEmbeddable<EmbeddableInput>, filters }
);
expect(execute).toHaveBeenCalledWith(
expect.objectContaining({ filters, openInSameTab: false })
);
expect(getHref).toHaveBeenCalledWith(expect.objectContaining({ filters }));
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import React from 'react';
import { IEmbeddable, EmbeddableInput } from '@kbn/embeddable-plugin/public';
import type { Query, Filter, TimeRange } from '@kbn/es-query';
import { APPLY_FILTER_TRIGGER } from '@kbn/data-plugin/public';
import type { ApplicationStart } from '@kbn/core/public';
import { CollectConfigProps as CollectConfigPropsBase } from '@kbn/kibana-utils-plugin/public';
import { reactToUiComponent } from '@kbn/kibana-react-plugin/public';
import {
Expand All @@ -20,7 +21,7 @@ import { DiscoverSetup } from '@kbn/discover-plugin/public';
import { ApplyGlobalFilterActionContext } from '@kbn/unified-search-plugin/public';
import { i18n } from '@kbn/i18n';
import { DataViewsService } from '@kbn/data-views-plugin/public';
import { execute, isCompatible, isLensEmbeddable } from './open_in_discover_helpers';
import { isCompatible, isLensEmbeddable, getHref, getLocation } from './open_in_discover_helpers';

interface EmbeddableQueryInput extends EmbeddableInput {
query?: Query;
Expand All @@ -35,6 +36,7 @@ interface UrlDrilldownDeps {
discover: Pick<DiscoverSetup, 'locator'>;
dataViews: () => Pick<DataViewsService, 'get'>;
hasDiscoverAccess: () => boolean;
application: () => ApplicationStart;
}

export type ActionContext = ApplyGlobalFilterActionContext;
Expand Down Expand Up @@ -119,14 +121,28 @@ export class OpenInDiscoverDrilldown
return this.deps.hasDiscoverAccess() && isLensEmbeddable(context.embeddable as IEmbeddable);
};

public readonly execute = async (config: Config, context: ActionContext) => {
execute({
public readonly getHref = async (config: Config, context: ActionContext) => {
return getHref({
discover: this.deps.discover,
dataViews: this.deps.dataViews(),
hasDiscoverAccess: this.deps.hasDiscoverAccess(),
...context,
embeddable: context.embeddable as IEmbeddable,
openInSameTab: !config.openInNewTab,
});
};

public readonly execute = async (config: Config, context: ActionContext) => {
if (config.openInNewTab) {
window.open(await this.getHref(config, context), '_blank');
} else {
const { app, path, state } = await getLocation({
discover: this.deps.discover,
dataViews: this.deps.dataViews(),
hasDiscoverAccess: this.deps.hasDiscoverAccess(),
...context,
embeddable: context.embeddable as IEmbeddable,
});
await this.deps.application().navigateToApp(app, { path, state });
}
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -38,14 +38,12 @@ export async function isCompatible({ hasDiscoverAccess, embeddable }: Context) {
}
}

export async function execute({
async function getDiscoverLocationParams({
embeddable,
discover,
filters,
openInSameTab,
dataViews,
timeFieldName,
}: Context) {
}: Pick<Context, 'dataViews' | 'embeddable' | 'filters' | 'timeFieldName'>) {
if (!isLensEmbeddable(embeddable)) {
// shouldn't be executed because of the isCompatible check
throw new Error('Can only be executed in the context of Lens visualization');
Expand All @@ -67,10 +65,72 @@ export async function execute({
timeRangeToApply = timeRange;
}
}
const discoverUrl = discover.locator?.getRedirectUrl({

return {
...args,
timeRange: timeRangeToApply,
filters: filtersToApply,
};
}

export async function getHref({
embeddable,
discover,
filters,
dataViews,
timeFieldName,
}: Context) {
const params = await getDiscoverLocationParams({
embeddable,
filters,
dataViews,
timeFieldName,
});

const discoverUrl = discover.locator?.getRedirectUrl(params);

return discoverUrl;
}

export async function getLocation({
embeddable,
discover,
filters,
dataViews,
timeFieldName,
}: Context) {
const params = await getDiscoverLocationParams({
embeddable,
filters,
dataViews,
timeFieldName,
});

const discoverLocation = discover.locator?.getLocation(params);

if (!discoverLocation) {
throw new Error('Discover location not found');
}

return discoverLocation;
}

export async function execute({
embeddable,
discover,
filters,
openInSameTab,
dataViews,
timeFieldName,
hasDiscoverAccess,
}: Context) {
const discoverUrl = await getHref({
embeddable,
discover,
filters,
dataViews,
timeFieldName,
hasDiscoverAccess,
});
window.open(discoverUrl, !openInSameTab ? '_blank' : '_self');
}

0 comments on commit 2de673f

Please sign in to comment.