Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

"Explore underlying data" in-chart action #69494

Merged
merged 24 commits into from
Jun 26, 2020
Merged
Show file tree
Hide file tree
Changes from 23 commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
4e180aa
refactor: 💡 rename folder to "explore_data"
streamich Jun 18, 2020
428bbab
style: 💄 check for "share" plugin in more semantic way
streamich Jun 18, 2020
11c6b64
refactor: 💡 move KibanaURL to a separate file
streamich Jun 18, 2020
795bfbb
feat: 🎸 add "Explore underlying data" in-chart action
streamich Jun 18, 2020
64ce4c4
fix: 🐛 fix imports after refactor
streamich Jun 18, 2020
55992da
feat: 🎸 add start.filtersFromContext to embeddable plugin
streamich Jun 18, 2020
a730c55
feat: 🎸 add type checkers to data plugin
streamich Jun 18, 2020
00a7aa3
feat: 🎸 better handle empty filters in Discover URL generator
streamich Jun 18, 2020
088feb1
feat: 🎸 implement .getUrl() method of explore data in-chart act
streamich Jun 18, 2020
302702f
feat: 🎸 add embeddable.filtersAndTimeRangeFromContext()
streamich Jun 18, 2020
5217996
feat: 🎸 improve getUrl() method of explore data action
streamich Jun 18, 2020
ec890c6
test: 💍 update test mock
streamich Jun 18, 2020
45f4cc4
Merge remote-tracking branch 'upstream/master' into chart-underlying-…
streamich Jun 23, 2020
9b5739a
fix possible stale hashHistory.location in discover
Dosant Jun 24, 2020
d2747a7
chore: 🤖 merge master
streamich Jun 25, 2020
eb61452
style: 💄 ensureHashHistoryLocation -> syncHistoryLocations
streamich Jun 25, 2020
406e02d
docs: ✏️ update autogenerated docs
streamich Jun 25, 2020
599382b
test: 💍 add in-chart "Explore underlying data" unit tests
streamich Jun 25, 2020
4ceefdd
test: 💍 add in-chart "Explore underlying data" functional tests
streamich Jun 25, 2020
0e29de3
test: 💍 clean-up custom time range after panel action tests
streamich Jun 25, 2020
424414f
chore: 🤖 fix embeddable plugin mocks
streamich Jun 25, 2020
dcef452
chore: 🤖 fix another mock
streamich Jun 25, 2020
905f0bc
test: 💍 add support for new action to pie chart service
streamich Jun 25, 2020
b567eb2
Merge remote-tracking branch 'upstream/master' into chart-underlying-…
streamich Jun 26, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->

[Home](./index.md) &gt; [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) &gt; [isFilter](./kibana-plugin-plugins-data-public.isfilter.md)

## isFilter variable

<b>Signature:</b>

```typescript
isFilter: (x: unknown) => x is Filter
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->

[Home](./index.md) &gt; [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) &gt; [isFilters](./kibana-plugin-plugins-data-public.isfilters.md)

## isFilters variable

<b>Signature:</b>

```typescript
isFilters: (x: unknown) => x is Filter[]
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->

[Home](./index.md) &gt; [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) &gt; [isQuery](./kibana-plugin-plugins-data-public.isquery.md)

## isQuery variable

<b>Signature:</b>

```typescript
isQuery: (x: unknown) => x is Query
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->

[Home](./index.md) &gt; [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) &gt; [isTimeRange](./kibana-plugin-plugins-data-public.istimerange.md)

## isTimeRange variable

<b>Signature:</b>

```typescript
isTimeRange: (x: unknown) => x is TimeRange
```
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,10 @@
| [getKbnTypeNames](./kibana-plugin-plugins-data-public.getkbntypenames.md) | Get the esTypes known by all kbnFieldTypes {<!-- -->Array<string>} |
| [indexPatterns](./kibana-plugin-plugins-data-public.indexpatterns.md) | |
| [injectSearchSourceReferences](./kibana-plugin-plugins-data-public.injectsearchsourcereferences.md) | |
| [isFilter](./kibana-plugin-plugins-data-public.isfilter.md) | |
| [isFilters](./kibana-plugin-plugins-data-public.isfilters.md) | |
| [isQuery](./kibana-plugin-plugins-data-public.isquery.md) | |
| [isTimeRange](./kibana-plugin-plugins-data-public.istimerange.md) | |
| [parseSearchSourceJSON](./kibana-plugin-plugins-data-public.parsesearchsourcejson.md) | |
| [QueryStringInput](./kibana-plugin-plugins-data-public.querystringinput.md) | |
| [search](./kibana-plugin-plugins-data-public.search.md) | |
Expand Down
10 changes: 10 additions & 0 deletions src/plugins/data/common/es_query/filters/meta_filter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -107,3 +107,13 @@ export const pinFilter = (filter: Filter) =>

export const unpinFilter = (filter: Filter) =>
!isFilterPinned(filter) ? filter : toggleFilterPinned(filter);

export const isFilter = (x: unknown): x is Filter =>
!!x &&
typeof x === 'object' &&
!!(x as Filter).meta &&
typeof (x as Filter).meta === 'object' &&
typeof (x as Filter).meta.disabled === 'boolean';

export const isFilters = (x: unknown): x is Filter[] =>
Array.isArray(x) && !x.find((y) => !isFilter(y));
3 changes: 2 additions & 1 deletion src/plugins/data/common/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,12 @@
export * from './constants';
export * from './es_query';
export * from './field_formats';
export * from './field_mapping';
export * from './index_patterns';
export * from './kbn_field_types';
export * from './query';
export * from './search';
export * from './search/aggs';
export * from './timefilter';
export * from './types';
export * from './utils';
export * from './field_mapping';
1 change: 1 addition & 0 deletions src/plugins/data/common/query/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,4 @@

export * from './filter_manager';
export * from './types';
export * from './is_query';
27 changes: 27 additions & 0 deletions src/plugins/data/common/query/is_query.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/*
* 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 { Query } from './types';

export const isQuery = (x: unknown): x is Query =>
!!x &&
typeof x === 'object' &&
typeof (x as Query).language === 'string' &&
(typeof (x as Query).query === 'string' ||
(typeof (x as Query).query === 'object' && !!(x as Query).query));
20 changes: 20 additions & 0 deletions src/plugins/data/common/timefilter/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/*
* 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.
*/

export { isTimeRange } from './is_time_range';
26 changes: 26 additions & 0 deletions src/plugins/data/common/timefilter/is_time_range.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/*
* 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 } from './types';

export const isTimeRange = (x: unknown): x is TimeRange =>
!!x &&
typeof x === 'object' &&
typeof (x as TimeRange).from === 'string' &&
typeof (x as TimeRange).to === 'string';
2 changes: 2 additions & 0 deletions src/plugins/data/public/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -440,6 +440,8 @@ export {
getKbnTypeNames,
} from '../common';

export { isTimeRange, isQuery, isFilter, isFilters } from '../common';

export * from '../common/field_mapping';

/*
Expand Down
20 changes: 20 additions & 0 deletions src/plugins/data/public/public.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -1278,6 +1278,26 @@ export interface ISearchStrategy<T extends TStrategyTypes> {
search: ISearch<T>;
}

// Warning: (ae-missing-release-tag) "isFilter" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public (undocumented)
export const isFilter: (x: unknown) => x is Filter;

// Warning: (ae-missing-release-tag) "isFilters" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public (undocumented)
export const isFilters: (x: unknown) => x is Filter[];

// Warning: (ae-missing-release-tag) "isQuery" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public (undocumented)
export const isQuery: (x: unknown) => x is Query;

// Warning: (ae-missing-release-tag) "isTimeRange" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public (undocumented)
export const isTimeRange: (x: unknown) => x is TimeRange;

// Warning: (ae-missing-release-tag) "ISyncSearchRequest" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public (undocumented)
Expand Down
2 changes: 1 addition & 1 deletion src/plugins/discover/public/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +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';
export { DISCOVER_APP_URL_GENERATOR, DiscoverUrlGeneratorState } from './url_generator';
15 changes: 14 additions & 1 deletion src/plugins/discover/public/kibana_services.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,10 +60,23 @@ export const [getDocViewsRegistry, setDocViewsRegistry] = createGetterSetter<Doc
'DocViewsRegistry'
);
/**
* Makes sure discover and context are using one instance of history
* Makes sure discover and context are using one instance of history.
*/
export const getHistory = _.once(() => createHashHistory());

/**
* Discover currently uses two `history` instances: one from Kibana Platform and
* another from `history` package. Below function is used every time Discover
streamich marked this conversation as resolved.
Show resolved Hide resolved
* app is loaded to synchronize both instances.
*
* This helper is temporary until https://github.com/elastic/kibana/issues/65161 is resolved.
*/
export const syncHistoryLocations = () => {
const h = getHistory();
Object.assign(h.location, createHashHistory().location);
return h;
};

streamich marked this conversation as resolved.
Show resolved Hide resolved
export const [getScopedHistory, setScopedHistory] = createGetterSetter<ScopedHistory>(
'scopedHistory'
);
Expand Down
2 changes: 2 additions & 0 deletions src/plugins/discover/public/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ import {
setServices,
setScopedHistory,
getScopedHistory,
syncHistoryLocations,
getServices,
} from './kibana_services';
import { createSavedSearchesLoader } from './saved_searches';
Expand Down Expand Up @@ -245,6 +246,7 @@ export class DiscoverPlugin
throw Error('Discover plugin method initializeInnerAngular is undefined');
}
setScopedHistory(params.history);
syncHistoryLocations();
appMounted();
const {
plugins: { data: dataStart },
Expand Down
6 changes: 4 additions & 2 deletions src/plugins/discover/public/url_generator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -98,11 +98,13 @@ export class DiscoverUrlGenerator
const queryState: QueryState = {};

if (query) appState.query = query;
if (filters) appState.filters = filters?.filter((f) => !esFilters.isFilterPinned(f));
if (filters && filters.length)
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 (filters && filters.length)
queryState.filters = filters?.filter((f) => esFilters.isFilterPinned(f));
if (refreshInterval) queryState.refreshInterval = refreshInterval;

let url = `${this.params.appBasePath}#/${savedSearchPath}`;
Expand Down
1 change: 1 addition & 0 deletions src/plugins/embeddable/kibana.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
"server": false,
"ui": true,
"requiredPlugins": [
"data",
streamich marked this conversation as resolved.
Show resolved Hide resolved
"inspector",
"uiActions"
],
Expand Down
1 change: 1 addition & 0 deletions src/plugins/embeddable/public/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ export {
ACTION_EDIT_PANEL,
Adapters,
AddPanelAction,
ChartActionContext,
Container,
ContainerInput,
ContainerOutput,
Expand Down
14 changes: 9 additions & 5 deletions src/plugins/embeddable/public/lib/triggers/triggers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,6 @@ export interface ValueClickTriggerContext<T extends IEmbeddable = IEmbeddable> {
};
}

export const isValueClickTriggerContext = (
context: ValueClickTriggerContext | RangeSelectTriggerContext
): context is ValueClickTriggerContext => context.data && 'data' in context.data;

export interface RangeSelectTriggerContext<T extends IEmbeddable = IEmbeddable> {
embeddable?: T;
data: {
Expand All @@ -53,8 +49,16 @@ export interface RangeSelectTriggerContext<T extends IEmbeddable = IEmbeddable>
};
}

export type ChartActionContext<T extends IEmbeddable = IEmbeddable> =
streamich marked this conversation as resolved.
Show resolved Hide resolved
| ValueClickTriggerContext<T>
| RangeSelectTriggerContext<T>;

export const isValueClickTriggerContext = (
context: ChartActionContext
): context is ValueClickTriggerContext => context.data && 'data' in context.data;

export const isRangeSelectTriggerContext = (
context: ValueClickTriggerContext | RangeSelectTriggerContext
context: ChartActionContext
): context is RangeSelectTriggerContext => context.data && 'range' in context.data;

export const CONTEXT_MENU_TRIGGER = 'CONTEXT_MENU_TRIGGER';
Expand Down
5 changes: 5 additions & 0 deletions src/plugins/embeddable/public/mocks.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import { coreMock } from '../../../core/public/mocks';
import { UiActionsService } from './lib/ui_actions';
import { CoreStart } from '../../../core/public';
import { Start as InspectorStart } from '../../inspector/public';
import { dataPluginMock } from '../../data/public/mocks';

// eslint-disable-next-line
import { inspectorPluginMock } from '../../inspector/public/mocks';
Expand Down Expand Up @@ -100,6 +101,8 @@ const createStartContract = (): Start => {
EmbeddablePanel: jest.fn(),
getEmbeddablePanel: jest.fn(),
getStateTransfer: jest.fn(() => createEmbeddableStateTransferMock() as EmbeddableStateTransfer),
filtersAndTimeRangeFromContext: jest.fn(),
filtersFromContext: jest.fn(),
};
return startContract;
};
Expand All @@ -108,11 +111,13 @@ const createInstance = (setupPlugins: Partial<EmbeddableSetupDependencies> = {})
const plugin = new EmbeddablePublicPlugin({} as any);
const setup = plugin.setup(coreMock.createSetup(), {
uiActions: setupPlugins.uiActions || uiActionsPluginMock.createSetupContract(),
data: dataPluginMock.createSetupContract(),
});
const doStart = (startPlugins: Partial<EmbeddableStartDependencies> = {}) =>
plugin.start(coreMock.createStart(), {
uiActions: startPlugins.uiActions || uiActionsPluginMock.createStartContract(),
inspector: inspectorPluginMock.createStartContract(),
data: dataPluginMock.createStartContract(),
});
return {
plugin,
Expand Down
Loading