mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 09:19:04 -04:00
Discover URL generator (#67937)
* feat: 🎸 stub discover_enhanced plugin * feat: 🎸 add Discover URL generator * chore: 🤖 remove x-pack plugin * fix: 🐛 fix types in URL generator * test: 💍 setup test file for Discover URL generator * feat: 🎸 expose Discover URL generator in start life-cycle * feat: 🎸 add ability to specify saved search ID in URL generator * docs: ✏️ add JSDoc for Discover URL generator * fix: 🐛 set correctly global filters in Discover URL generator * docs: ✏️ remove wrong comment in JsDoc * style: 💄 format single arg arrow function with parens * chore: 🤖 disable toggles in Dicover sample drilldown * feat: 🎸 use Discover URL generator in example plugin * test: 💍 add urlGenerator mock * test: 💍 add .registerUrlGenerator() test mock * test: 💍 correct Karma mock for "share" plugin URL generator
This commit is contained in:
parent
a6e9caefe4
commit
7ea8ef1fba
13 changed files with 451 additions and 18 deletions
|
@ -254,6 +254,9 @@ export const npSetup = {
|
|||
},
|
||||
share: {
|
||||
register: () => {},
|
||||
urlGenerators: {
|
||||
registerUrlGenerator: () => {},
|
||||
},
|
||||
},
|
||||
devTools: {
|
||||
register: () => {},
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
{
|
||||
"id": "discover",
|
||||
"version": "kibana",
|
||||
"optionalPlugins": ["share"],
|
||||
"server": true,
|
||||
"ui": true,
|
||||
"requiredPlugins": [
|
||||
|
|
|
@ -27,3 +27,4 @@ export function plugin(initializerContext: PluginInitializerContext) {
|
|||
|
||||
export { SavedSearch, SavedSearchLoader, createSavedSearchesLoader } from './saved_searches';
|
||||
export { ISearchEmbeddable, SEARCH_EMBEDDABLE_TYPE, SearchInput } from './application/embeddable';
|
||||
export { DISCOVER_APP_URL_GENERATOR } from './url_generator';
|
||||
|
|
|
@ -34,6 +34,9 @@ const createSetupContract = (): Setup => {
|
|||
const createStartContract = (): Start => {
|
||||
const startContract: Start = {
|
||||
savedSearchLoader: {} as any,
|
||||
urlGenerator: {
|
||||
createUrl: jest.fn(),
|
||||
} as any,
|
||||
};
|
||||
return startContract;
|
||||
};
|
||||
|
|
|
@ -34,7 +34,7 @@ import { UiActionsStart, UiActionsSetup } from 'src/plugins/ui_actions/public';
|
|||
import { EmbeddableStart, EmbeddableSetup } from 'src/plugins/embeddable/public';
|
||||
import { ChartsPluginStart } from 'src/plugins/charts/public';
|
||||
import { NavigationPublicPluginStart as NavigationStart } from 'src/plugins/navigation/public';
|
||||
import { SharePluginStart } from 'src/plugins/share/public';
|
||||
import { SharePluginStart, SharePluginSetup, UrlGeneratorContract } from 'src/plugins/share/public';
|
||||
import { VisualizationsStart, VisualizationsSetup } from 'src/plugins/visualizations/public';
|
||||
import { KibanaLegacySetup } from 'src/plugins/kibana_legacy/public';
|
||||
import { HomePublicPluginSetup } from 'src/plugins/home/public';
|
||||
|
@ -43,7 +43,7 @@ import { DataPublicPluginStart, DataPublicPluginSetup, esFilters } from '../../d
|
|||
import { SavedObjectLoader } from '../../saved_objects/public';
|
||||
import { createKbnUrlTracker } from '../../kibana_utils/public';
|
||||
import { DEFAULT_APP_CATEGORIES } from '../../../core/public';
|
||||
|
||||
import { UrlGeneratorState } from '../../share/public';
|
||||
import { DocViewInput, DocViewInputFn } from './application/doc_views/doc_views_types';
|
||||
import { DocViewsRegistry } from './application/doc_views/doc_views_registry';
|
||||
import { DocViewTable } from './application/components/table/table';
|
||||
|
@ -59,6 +59,17 @@ import {
|
|||
import { createSavedSearchesLoader } from './saved_searches';
|
||||
import { registerFeature } from './register_feature';
|
||||
import { buildServices } from './build_services';
|
||||
import {
|
||||
DiscoverUrlGeneratorState,
|
||||
DISCOVER_APP_URL_GENERATOR,
|
||||
DiscoverUrlGenerator,
|
||||
} from './url_generator';
|
||||
|
||||
declare module '../../share/public' {
|
||||
export interface UrlGeneratorStateMapping {
|
||||
[DISCOVER_APP_URL_GENERATOR]: UrlGeneratorState<DiscoverUrlGeneratorState>;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @public
|
||||
|
@ -76,12 +87,31 @@ export interface DiscoverSetup {
|
|||
|
||||
export interface DiscoverStart {
|
||||
savedSearchLoader: SavedObjectLoader;
|
||||
|
||||
/**
|
||||
* `share` plugin URL generator for Discover app. Use it to generate links into
|
||||
* Discover application, example:
|
||||
*
|
||||
* ```ts
|
||||
* const url = await plugins.discover.urlGenerator.createUrl({
|
||||
* savedSearchId: '571aaf70-4c88-11e8-b3d7-01146121b73d',
|
||||
* indexPatternId: 'c367b774-a4c2-11ea-bb37-0242ac130002',
|
||||
* timeRange: {
|
||||
* to: 'now',
|
||||
* from: 'now-15m',
|
||||
* mode: 'relative',
|
||||
* },
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
readonly urlGenerator: undefined | UrlGeneratorContract<'DISCOVER_APP_URL_GENERATOR'>;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export interface DiscoverSetupPlugins {
|
||||
share?: SharePluginSetup;
|
||||
uiActions: UiActionsSetup;
|
||||
embeddable: EmbeddableSetup;
|
||||
kibanaLegacy: KibanaLegacySetup;
|
||||
|
@ -122,6 +152,7 @@ export class DiscoverPlugin
|
|||
private stopUrlTracking: (() => void) | undefined = undefined;
|
||||
private servicesInitialized: boolean = false;
|
||||
private innerAngularInitialized: boolean = false;
|
||||
private urlGenerator?: DiscoverStart['urlGenerator'];
|
||||
|
||||
/**
|
||||
* why are those functions public? they are needed for some mocha tests
|
||||
|
@ -131,6 +162,17 @@ export class DiscoverPlugin
|
|||
public initializeServices?: () => Promise<{ core: CoreStart; plugins: DiscoverStartPlugins }>;
|
||||
|
||||
setup(core: CoreSetup<DiscoverStartPlugins, DiscoverStart>, plugins: DiscoverSetupPlugins) {
|
||||
const baseUrl = core.http.basePath.prepend('/app/discover');
|
||||
|
||||
if (plugins.share) {
|
||||
this.urlGenerator = plugins.share.urlGenerators.registerUrlGenerator(
|
||||
new DiscoverUrlGenerator({
|
||||
appBasePath: baseUrl,
|
||||
useHash: core.uiSettings.get('state:storeInSessionStorage'),
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
this.docViewsRegistry = new DocViewsRegistry();
|
||||
setDocViewsRegistry(this.docViewsRegistry);
|
||||
this.docViewsRegistry.addDocView({
|
||||
|
@ -158,7 +200,7 @@ export class DiscoverPlugin
|
|||
// so history is lazily created (when app is mounted)
|
||||
// this prevents redundant `#` when not in discover app
|
||||
getHistory: getScopedHistory,
|
||||
baseUrl: core.http.basePath.prepend('/app/discover'),
|
||||
baseUrl,
|
||||
defaultSubUrl: '#/',
|
||||
storageKey: `lastUrl:${core.http.basePath.get()}:discover`,
|
||||
navLinkUpdater$: this.appStateUpdater,
|
||||
|
@ -266,6 +308,7 @@ export class DiscoverPlugin
|
|||
};
|
||||
|
||||
return {
|
||||
urlGenerator: this.urlGenerator,
|
||||
savedSearchLoader: createSavedSearchesLoader({
|
||||
savedObjectsClient: core.savedObjects.client,
|
||||
indexPatterns: plugins.data.indexPatterns,
|
||||
|
|
259
src/plugins/discover/public/url_generator.test.ts
Normal file
259
src/plugins/discover/public/url_generator.test.ts
Normal file
|
@ -0,0 +1,259 @@
|
|||
/*
|
||||
* Licensed to Elasticsearch B.V. under one or more contributor
|
||||
* license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright
|
||||
* ownership. Elasticsearch B.V. licenses this file to you under
|
||||
* the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
import { DiscoverUrlGenerator } from './url_generator';
|
||||
import { hashedItemStore, getStatesFromKbnUrl } from '../../kibana_utils/public';
|
||||
// eslint-disable-next-line
|
||||
import { mockStorage } from '../../kibana_utils/public/storage/hashed_item_store/mock';
|
||||
import { FilterStateStore } from '../../data/common';
|
||||
|
||||
const appBasePath: string = 'xyz/app/discover';
|
||||
const indexPatternId: string = 'c367b774-a4c2-11ea-bb37-0242ac130002';
|
||||
const savedSearchId: string = '571aaf70-4c88-11e8-b3d7-01146121b73d';
|
||||
|
||||
interface SetupParams {
|
||||
useHash?: boolean;
|
||||
}
|
||||
|
||||
const setup = async ({ useHash = false }: SetupParams = {}) => {
|
||||
const generator = new DiscoverUrlGenerator({
|
||||
appBasePath,
|
||||
useHash,
|
||||
});
|
||||
|
||||
return {
|
||||
generator,
|
||||
};
|
||||
};
|
||||
|
||||
beforeEach(() => {
|
||||
// @ts-ignore
|
||||
hashedItemStore.storage = mockStorage;
|
||||
});
|
||||
|
||||
describe('Discover url generator', () => {
|
||||
test('can create a link to Discover with no state and no saved search', async () => {
|
||||
const { generator } = await setup();
|
||||
const url = await generator.createUrl({});
|
||||
const { _a, _g } = getStatesFromKbnUrl(url, ['_a', '_g']);
|
||||
|
||||
expect(url.startsWith(appBasePath)).toBe(true);
|
||||
expect(_a).toEqual({});
|
||||
expect(_g).toEqual({});
|
||||
});
|
||||
|
||||
test('can create a link to a saved search in Discover', async () => {
|
||||
const { generator } = await setup();
|
||||
const url = await generator.createUrl({ savedSearchId });
|
||||
const { _a, _g } = getStatesFromKbnUrl(url, ['_a', '_g']);
|
||||
|
||||
expect(url.startsWith(`${appBasePath}#/${savedSearchId}`)).toBe(true);
|
||||
expect(_a).toEqual({});
|
||||
expect(_g).toEqual({});
|
||||
});
|
||||
|
||||
test('can specify specific index pattern', async () => {
|
||||
const { generator } = await setup();
|
||||
const url = await generator.createUrl({
|
||||
indexPatternId,
|
||||
});
|
||||
const { _a, _g } = getStatesFromKbnUrl(url, ['_a', '_g']);
|
||||
|
||||
expect(_a).toEqual({
|
||||
index: indexPatternId,
|
||||
});
|
||||
expect(_g).toEqual({});
|
||||
});
|
||||
|
||||
test('can specify specific time range', async () => {
|
||||
const { generator } = await setup();
|
||||
const url = await generator.createUrl({
|
||||
timeRange: { to: 'now', from: 'now-15m', mode: 'relative' },
|
||||
});
|
||||
const { _a, _g } = getStatesFromKbnUrl(url, ['_a', '_g']);
|
||||
|
||||
expect(_a).toEqual({});
|
||||
expect(_g).toEqual({
|
||||
time: {
|
||||
from: 'now-15m',
|
||||
mode: 'relative',
|
||||
to: 'now',
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
test('can specify query', async () => {
|
||||
const { generator } = await setup();
|
||||
const url = await generator.createUrl({
|
||||
query: {
|
||||
language: 'kuery',
|
||||
query: 'foo',
|
||||
},
|
||||
});
|
||||
const { _a, _g } = getStatesFromKbnUrl(url, ['_a', '_g']);
|
||||
|
||||
expect(_a).toEqual({
|
||||
query: {
|
||||
language: 'kuery',
|
||||
query: 'foo',
|
||||
},
|
||||
});
|
||||
expect(_g).toEqual({});
|
||||
});
|
||||
|
||||
test('can specify local and global filters', async () => {
|
||||
const { generator } = await setup();
|
||||
const url = await generator.createUrl({
|
||||
filters: [
|
||||
{
|
||||
meta: {
|
||||
alias: 'foo',
|
||||
disabled: false,
|
||||
negate: false,
|
||||
},
|
||||
$state: {
|
||||
store: FilterStateStore.APP_STATE,
|
||||
},
|
||||
},
|
||||
{
|
||||
meta: {
|
||||
alias: 'bar',
|
||||
disabled: false,
|
||||
negate: false,
|
||||
},
|
||||
$state: {
|
||||
store: FilterStateStore.GLOBAL_STATE,
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
const { _a, _g } = getStatesFromKbnUrl(url, ['_a', '_g']);
|
||||
|
||||
expect(_a).toEqual({
|
||||
filters: [
|
||||
{
|
||||
$state: {
|
||||
store: 'appState',
|
||||
},
|
||||
meta: {
|
||||
alias: 'foo',
|
||||
disabled: false,
|
||||
negate: false,
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
expect(_g).toEqual({
|
||||
filters: [
|
||||
{
|
||||
$state: {
|
||||
store: 'globalState',
|
||||
},
|
||||
meta: {
|
||||
alias: 'bar',
|
||||
disabled: false,
|
||||
negate: false,
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
});
|
||||
|
||||
test('can set refresh interval', async () => {
|
||||
const { generator } = await setup();
|
||||
const url = await generator.createUrl({
|
||||
refreshInterval: {
|
||||
pause: false,
|
||||
value: 666,
|
||||
},
|
||||
});
|
||||
const { _a, _g } = getStatesFromKbnUrl(url, ['_a', '_g']);
|
||||
|
||||
expect(_a).toEqual({});
|
||||
expect(_g).toEqual({
|
||||
refreshInterval: {
|
||||
pause: false,
|
||||
value: 666,
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
test('can set time range', async () => {
|
||||
const { generator } = await setup();
|
||||
const url = await generator.createUrl({
|
||||
timeRange: {
|
||||
from: 'now-3h',
|
||||
to: 'now',
|
||||
},
|
||||
});
|
||||
const { _a, _g } = getStatesFromKbnUrl(url, ['_a', '_g']);
|
||||
|
||||
expect(_a).toEqual({});
|
||||
expect(_g).toEqual({
|
||||
time: {
|
||||
from: 'now-3h',
|
||||
to: 'now',
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
describe('useHash property', () => {
|
||||
describe('when default useHash is set to false', () => {
|
||||
test('when using default, sets index pattern ID in the generated URL', async () => {
|
||||
const { generator } = await setup();
|
||||
const url = await generator.createUrl({
|
||||
indexPatternId,
|
||||
});
|
||||
|
||||
expect(url.indexOf(indexPatternId) > -1).toBe(true);
|
||||
});
|
||||
|
||||
test('when enabling useHash, does not set index pattern ID in the generated URL', async () => {
|
||||
const { generator } = await setup();
|
||||
const url = await generator.createUrl({
|
||||
useHash: true,
|
||||
indexPatternId,
|
||||
});
|
||||
|
||||
expect(url.indexOf(indexPatternId) > -1).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('when default useHash is set to true', () => {
|
||||
test('when using default, does not set index pattern ID in the generated URL', async () => {
|
||||
const { generator } = await setup({ useHash: true });
|
||||
const url = await generator.createUrl({
|
||||
indexPatternId,
|
||||
});
|
||||
|
||||
expect(url.indexOf(indexPatternId) > -1).toBe(false);
|
||||
});
|
||||
|
||||
test('when disabling useHash, sets index pattern ID in the generated URL', async () => {
|
||||
const { generator } = await setup();
|
||||
const url = await generator.createUrl({
|
||||
useHash: false,
|
||||
indexPatternId,
|
||||
});
|
||||
|
||||
expect(url.indexOf(indexPatternId) > -1).toBe(true);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
114
src/plugins/discover/public/url_generator.ts
Normal file
114
src/plugins/discover/public/url_generator.ts
Normal file
|
@ -0,0 +1,114 @@
|
|||
/*
|
||||
* Licensed to Elasticsearch B.V. under one or more contributor
|
||||
* license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright
|
||||
* ownership. Elasticsearch B.V. licenses this file to you under
|
||||
* the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
import {
|
||||
TimeRange,
|
||||
Filter,
|
||||
Query,
|
||||
esFilters,
|
||||
QueryState,
|
||||
RefreshInterval,
|
||||
} from '../../data/public';
|
||||
import { setStateToKbnUrl } from '../../kibana_utils/public';
|
||||
import { UrlGeneratorsDefinition } from '../../share/public';
|
||||
|
||||
export const DISCOVER_APP_URL_GENERATOR = 'DISCOVER_APP_URL_GENERATOR';
|
||||
|
||||
export interface DiscoverUrlGeneratorState {
|
||||
/**
|
||||
* Optionally set saved search ID.
|
||||
*/
|
||||
savedSearchId?: string;
|
||||
|
||||
/**
|
||||
* Optionally set index pattern ID.
|
||||
*/
|
||||
indexPatternId?: string;
|
||||
|
||||
/**
|
||||
* Optionally set the time range in the time picker.
|
||||
*/
|
||||
timeRange?: TimeRange;
|
||||
|
||||
/**
|
||||
* Optionally set the refresh interval.
|
||||
*/
|
||||
refreshInterval?: RefreshInterval;
|
||||
|
||||
/**
|
||||
* Optionally apply filers.
|
||||
*/
|
||||
filters?: Filter[];
|
||||
|
||||
/**
|
||||
* Optionally set a query. NOTE: if given and used in conjunction with `dashboardId`, and the
|
||||
* saved dashboard has a query saved with it, this will _replace_ that query.
|
||||
*/
|
||||
query?: Query;
|
||||
|
||||
/**
|
||||
* If not given, will use the uiSettings configuration for `storeInSessionStorage`. useHash determines
|
||||
* whether to hash the data in the url to avoid url length issues.
|
||||
*/
|
||||
useHash?: boolean;
|
||||
}
|
||||
|
||||
interface Params {
|
||||
appBasePath: string;
|
||||
useHash: boolean;
|
||||
}
|
||||
|
||||
export class DiscoverUrlGenerator
|
||||
implements UrlGeneratorsDefinition<typeof DISCOVER_APP_URL_GENERATOR> {
|
||||
constructor(private readonly params: Params) {}
|
||||
|
||||
public readonly id = DISCOVER_APP_URL_GENERATOR;
|
||||
|
||||
public readonly createUrl = async ({
|
||||
filters,
|
||||
indexPatternId,
|
||||
query,
|
||||
refreshInterval,
|
||||
savedSearchId,
|
||||
timeRange,
|
||||
useHash = this.params.useHash,
|
||||
}: DiscoverUrlGeneratorState): Promise<string> => {
|
||||
const savedSearchPath = savedSearchId ? encodeURIComponent(savedSearchId) : '';
|
||||
const appState: {
|
||||
query?: Query;
|
||||
filters?: Filter[];
|
||||
index?: string;
|
||||
} = {};
|
||||
const queryState: QueryState = {};
|
||||
|
||||
if (query) appState.query = query;
|
||||
if (filters) appState.filters = filters?.filter((f) => !esFilters.isFilterPinned(f));
|
||||
if (indexPatternId) appState.index = indexPatternId;
|
||||
|
||||
if (timeRange) queryState.time = timeRange;
|
||||
if (filters) queryState.filters = filters?.filter((f) => esFilters.isFilterPinned(f));
|
||||
if (refreshInterval) queryState.refreshInterval = refreshInterval;
|
||||
|
||||
let url = `${this.params.appBasePath}#/${savedSearchPath}`;
|
||||
url = setStateToKbnUrl<QueryState>('_g', queryState, { useHash }, url);
|
||||
url = setStateToKbnUrl('_a', appState, { useHash }, url);
|
||||
|
||||
return url;
|
||||
};
|
||||
}
|
|
@ -19,16 +19,17 @@
|
|||
|
||||
import { CoreStart, StartServicesAccessor } from '../../../../core/public';
|
||||
|
||||
export interface StartServices<Plugins = unknown, OwnContract = unknown> {
|
||||
export interface StartServices<Plugins = unknown, OwnContract = unknown, Core = CoreStart> {
|
||||
plugins: Plugins;
|
||||
self: OwnContract;
|
||||
core: CoreStart;
|
||||
core: Core;
|
||||
}
|
||||
|
||||
export type StartServicesGetter<Plugins = unknown, OwnContract = unknown> = () => StartServices<
|
||||
Plugins,
|
||||
OwnContract
|
||||
>;
|
||||
export type StartServicesGetter<
|
||||
Plugins = unknown,
|
||||
OwnContract = unknown,
|
||||
Core = CoreStart
|
||||
> = () => StartServices<Plugins, OwnContract>;
|
||||
|
||||
/**
|
||||
* Use this utility to create a synchronous *start* service getter in *setup*
|
||||
|
|
|
@ -24,7 +24,7 @@ import { UrlGeneratorInternal } from './url_generator_internal';
|
|||
import { UrlGeneratorContract } from './url_generator_contract';
|
||||
|
||||
export interface UrlGeneratorsStart {
|
||||
getUrlGenerator: (urlGeneratorId: UrlGeneratorId) => UrlGeneratorContract<UrlGeneratorId>;
|
||||
getUrlGenerator: <T extends UrlGeneratorId>(urlGeneratorId: T) => UrlGeneratorContract<T>;
|
||||
}
|
||||
|
||||
export interface UrlGeneratorsSetup {
|
||||
|
|
|
@ -5,6 +5,6 @@
|
|||
"configPath": ["ui_actions_enhanced_examples"],
|
||||
"server": false,
|
||||
"ui": true,
|
||||
"requiredPlugins": ["uiActionsEnhanced", "data"],
|
||||
"requiredPlugins": ["uiActionsEnhanced", "data", "discover"],
|
||||
"optionalPlugins": []
|
||||
}
|
||||
|
|
|
@ -31,9 +31,7 @@ export const DiscoverDrilldownConfig: React.FC<DiscoverDrilldownConfigProps> = (
|
|||
onIndexPatternSelect,
|
||||
customIndexPattern,
|
||||
onCustomIndexPatternToggle,
|
||||
carryFiltersAndQuery,
|
||||
onCarryFiltersAndQueryToggle,
|
||||
carryTimeRange,
|
||||
onCarryTimeRangeToggle,
|
||||
}) => {
|
||||
return (
|
||||
|
@ -82,9 +80,10 @@ export const DiscoverDrilldownConfig: React.FC<DiscoverDrilldownConfigProps> = (
|
|||
{!!onCarryFiltersAndQueryToggle && (
|
||||
<EuiFormRow hasChildLabel={false}>
|
||||
<EuiSwitch
|
||||
disabled
|
||||
name="carryFiltersAndQuery"
|
||||
label="Carry over filters and query"
|
||||
checked={!!carryFiltersAndQuery}
|
||||
checked={false}
|
||||
onChange={onCarryFiltersAndQueryToggle}
|
||||
/>
|
||||
</EuiFormRow>
|
||||
|
@ -92,9 +91,10 @@ export const DiscoverDrilldownConfig: React.FC<DiscoverDrilldownConfigProps> = (
|
|||
{!!onCarryTimeRangeToggle && (
|
||||
<EuiFormRow hasChildLabel={false}>
|
||||
<EuiSwitch
|
||||
disabled
|
||||
name="carryTimeRange"
|
||||
label="Carry over time range"
|
||||
checked={!!carryTimeRange}
|
||||
checked={false}
|
||||
onChange={onCarryTimeRangeToggle}
|
||||
/>
|
||||
</EuiFormRow>
|
||||
|
|
|
@ -22,7 +22,7 @@ const isOutputWithIndexPatterns = (
|
|||
};
|
||||
|
||||
export interface Params {
|
||||
start: StartServicesGetter<Pick<Start, 'data'>>;
|
||||
start: StartServicesGetter<Pick<Start, 'data' | 'discover'>>;
|
||||
}
|
||||
|
||||
export class DashboardToDiscoverDrilldown implements Drilldown<Config, ActionContext> {
|
||||
|
@ -54,6 +54,10 @@ export class DashboardToDiscoverDrilldown implements Drilldown<Config, ActionCon
|
|||
};
|
||||
|
||||
private readonly getPath = async (config: Config, context: ActionContext): Promise<string> => {
|
||||
const { urlGenerator } = this.params.start().plugins.discover;
|
||||
|
||||
if (!urlGenerator) throw new Error('Discover URL generator not available.');
|
||||
|
||||
let indexPatternId =
|
||||
!!config.customIndexPattern && !!config.indexPatternId ? config.indexPatternId : '';
|
||||
|
||||
|
@ -64,8 +68,9 @@ export class DashboardToDiscoverDrilldown implements Drilldown<Config, ActionCon
|
|||
}
|
||||
}
|
||||
|
||||
const index = indexPatternId ? `,index:'${indexPatternId}'` : '';
|
||||
return `#/?_g=(filters:!(),refreshInterval:(pause:!f,value:900000),time:(from:now-7d,to:now))&_a=(columns:!(_source),filters:!()${index},interval:auto,query:(language:kuery,query:''),sort:!())`;
|
||||
return await urlGenerator.createUrl({
|
||||
indexPatternId,
|
||||
});
|
||||
};
|
||||
|
||||
public readonly getHref = async (config: Config, context: ActionContext): Promise<string> => {
|
||||
|
|
|
@ -14,14 +14,17 @@ import { DashboardHelloWorldDrilldown } from './dashboard_hello_world_drilldown'
|
|||
import { DashboardToUrlDrilldown } from './dashboard_to_url_drilldown';
|
||||
import { DashboardToDiscoverDrilldown } from './dashboard_to_discover_drilldown';
|
||||
import { createStartServicesGetter } from '../../../../src/plugins/kibana_utils/public';
|
||||
import { DiscoverSetup, DiscoverStart } from '../../../../src/plugins/discover/public';
|
||||
|
||||
export interface SetupDependencies {
|
||||
data: DataPublicPluginSetup;
|
||||
discover: DiscoverSetup;
|
||||
uiActionsEnhanced: AdvancedUiActionsSetup;
|
||||
}
|
||||
|
||||
export interface StartDependencies {
|
||||
data: DataPublicPluginStart;
|
||||
discover: DiscoverStart;
|
||||
uiActionsEnhanced: AdvancedUiActionsStart;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue