Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
Expand Up @@ -9,9 +9,10 @@ Helper to setup two-way syncing of global data and a state container
<b>Signature:</b>

```typescript
connectToQueryState: <S extends QueryState>({ timefilter: { timefilter }, filterManager, state$, }: Pick<QueryStart | QuerySetup, 'timefilter' | 'filterManager' | 'state$'>, stateContainer: BaseStateContainer<S>, syncConfig: {
connectToQueryState: <S extends QueryState>({ timefilter: { timefilter }, filterManager, queryString, state$, }: Pick<QueryStart | QuerySetup, 'timefilter' | 'filterManager' | 'queryString' | 'state$'>, stateContainer: BaseStateContainer<S>, syncConfig: {
time?: boolean;
refreshInterval?: boolean;
filters?: FilterStateStore | boolean;
query?: boolean;
}) => () => void
```
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ export interface QueryState
| Property | Type | Description |
| --- | --- | --- |
| [filters](./kibana-plugin-plugins-data-public.querystate.filters.md) | <code>Filter[]</code> | |
| [query](./kibana-plugin-plugins-data-public.querystate.query.md) | <code>Query</code> | |
| [refreshInterval](./kibana-plugin-plugins-data-public.querystate.refreshinterval.md) | <code>RefreshInterval</code> | |
| [time](./kibana-plugin-plugins-data-public.querystate.time.md) | <code>TimeRange</code> | |

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; [QueryState](./kibana-plugin-plugins-data-public.querystate.md) &gt; [query](./kibana-plugin-plugins-data-public.querystate.query.md)

## QueryState.query property

<b>Signature:</b>

```typescript
query?: Query;
```
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ Helper to setup syncing of global data with the URL
<b>Signature:</b>

```typescript
syncQueryStateWithUrl: (query: Pick<QueryStart | QuerySetup, 'filterManager' | 'timefilter' | 'state$'>, kbnUrlStateStorage: IKbnUrlStateStorage) => {
syncQueryStateWithUrl: (query: Pick<QueryStart | QuerySetup, 'filterManager' | 'timefilter' | 'queryString' | 'state$'>, kbnUrlStateStorage: IKbnUrlStateStorage) => {
stop: () => void;
hasInheritedQueryFromUrl: boolean;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
* under the License.
*/

import React, { useEffect, useRef, useState, useCallback } from 'react';
import React, { useEffect, useRef, useState } from 'react';
import { History } from 'history';
import { FormattedMessage, I18nProvider } from '@kbn/i18n/react';
import { Router } from 'react-router-dom';
Expand Down Expand Up @@ -85,16 +85,9 @@ const App = ({ navigation, data, history, kbnUrlStateStorage }: StateDemoAppDeps
useGlobalStateSyncing(data.query, kbnUrlStateStorage);
useAppStateSyncing(appStateContainer, data.query, kbnUrlStateStorage);

const onQuerySubmit = useCallback(
({ query }) => {
appStateContainer.set({ ...appState, query });
},
[appStateContainer, appState]
);

const indexPattern = useIndexPattern(data);
if (!indexPattern)
return <div>No index pattern found. Please create an intex patter before loading...</div>;
return <div>No index pattern found. Please create an index patter before loading...</div>;

// Render the application DOM.
// Note that `navigation.ui.TopNavMenu` is a stateful component exported on the `navigation` plugin's start contract.
Expand All @@ -107,8 +100,6 @@ const App = ({ navigation, data, history, kbnUrlStateStorage }: StateDemoAppDeps
showSearchBar={true}
indexPatterns={[indexPattern]}
useDefaultBehaviors={true}
onQuerySubmit={onQuerySubmit}
query={appState.query}
showSaveQuery={true}
/>
<EuiPage restrictWidth="1000px">
Expand Down Expand Up @@ -200,7 +191,7 @@ function useAppStateSyncing<AppState extends QueryState>(
const stopSyncingQueryAppStateWithStateContainer = connectToQueryState(
query,
appStateContainer,
{ filters: esFilters.FilterStateStore.APP_STATE }
{ filters: esFilters.FilterStateStore.APP_STATE, query: true }
);

// sets up syncing app state container with url
Expand Down
5 changes: 4 additions & 1 deletion src/plugins/dashboard/public/application/dashboard_app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,10 @@ export interface DashboardAppScope extends ng.IScope {
expandedPanel?: string;
getShouldShowEditHelp: () => boolean;
getShouldShowViewHelp: () => boolean;
updateQueryAndFetch: ({ query, dateRange }: { query: Query; dateRange?: TimeRange }) => void;
handleRefresh: (
{ query, dateRange }: { query?: Query; dateRange: TimeRange },
isUpdate?: boolean
) => void;
topNavMenu: any;
showAddPanel: any;
showSaveQuery: boolean;
Expand Down
103 changes: 39 additions & 64 deletions src/plugins/dashboard/public/application/dashboard_app_controller.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,24 +25,21 @@ import React, { useState, ReactElement } from 'react';
import ReactDOM from 'react-dom';
import angular from 'angular';

import { Observable, pipe, Subscription } from 'rxjs';
import { filter, map, mapTo, startWith, switchMap } from 'rxjs/operators';
import { Observable, pipe, Subscription, merge } from 'rxjs';
import { filter, map, debounceTime, mapTo, startWith, switchMap } from 'rxjs/operators';
import { History } from 'history';
import { SavedObjectSaveOpts } from 'src/plugins/saved_objects/public';
import { NavigationPublicPluginStart as NavigationStart } from 'src/plugins/navigation/public';
import { TimeRange } from 'src/plugins/data/public';
import { DashboardEmptyScreen, DashboardEmptyScreenProps } from './dashboard_empty_screen';

import {
connectToQueryState,
esFilters,
IndexPattern,
IndexPatternsContract,
Query,
QueryState,
SavedQuery,
syncQueryStateWithUrl,
UI_SETTINGS,
} from '../../../data/public';
import { getSavedObjectFinder, SaveResult, showSaveModal } from '../../../saved_objects/public';

Expand Down Expand Up @@ -81,8 +78,8 @@ import {
addFatalError,
AngularHttpError,
KibanaLegacyStart,
migrateLegacyQuery,
subscribeWithScope,
migrateLegacyQuery,
} from '../../../kibana_legacy/public';

export interface DashboardAppControllerDependencies extends RenderDeps {
Expand Down Expand Up @@ -127,7 +124,6 @@ export class DashboardAppController {
$route,
$routeParams,
dashboardConfig,
localStorage,
indexPatterns,
savedQueryService,
embeddable,
Expand All @@ -153,8 +149,8 @@ export class DashboardAppController {
navigation,
}: DashboardAppControllerDependencies) {
const filterManager = queryService.filterManager;
const queryFilter = filterManager;
const timefilter = queryService.timefilter.timefilter;
const queryStringManager = queryService.queryString;
const isEmbeddedExternally = Boolean($routeParams.embed);

// url param rules should only apply when embedded (e.g. url?embed=true)
Expand Down Expand Up @@ -188,20 +184,30 @@ export class DashboardAppController {
// sync initial app filters from state to filterManager
// if there is an existing similar global filter, then leave it as global
filterManager.setAppFilters(_.cloneDeep(dashboardStateManager.appState.filters));
queryStringManager.setQuery(migrateLegacyQuery(dashboardStateManager.appState.query));

// setup syncing of app filters between appState and filterManager
const stopSyncingAppFilters = connectToQueryState(
queryService,
{
set: ({ filters }) => dashboardStateManager.setFilters(filters || []),
get: () => ({ filters: dashboardStateManager.appState.filters }),
set: ({ filters, query }) => {
dashboardStateManager.setFilters(filters || []);
dashboardStateManager.setQuery(query || queryStringManager.getDefaultQuery());
},
get: () => ({
filters: dashboardStateManager.appState.filters,
query: dashboardStateManager.getQuery(),
}),
state$: dashboardStateManager.appState$.pipe(
map((state) => ({
filters: state.filters,
query: queryStringManager.formatQuery(state.query),
}))
),
},
{
filters: esFilters.FilterStateStore.APP_STATE,
query: true,
}
);

Expand Down Expand Up @@ -331,7 +337,7 @@ export class DashboardAppController {
const isEmptyInReadonlyMode = shouldShowUnauthorizedEmptyState();
return {
id: dashboardStateManager.savedDashboard.id || '',
filters: queryFilter.getFilters(),
filters: filterManager.getFilters(),
hidePanelTitles: dashboardStateManager.getHidePanelTitles(),
query: $scope.model.query,
timeRange: {
Expand All @@ -356,7 +362,7 @@ export class DashboardAppController {
// https://github.com/angular/angular.js/wiki/Understanding-Scopes
$scope.model = {
query: dashboardStateManager.getQuery(),
filters: queryFilter.getFilters(),
filters: filterManager.getFilters(),
timeRestore: dashboardStateManager.getTimeRestore(),
title: dashboardStateManager.getTitle(),
description: dashboardStateManager.getDescription(),
Expand Down Expand Up @@ -420,12 +426,12 @@ export class DashboardAppController {
if (
!esFilters.compareFilters(
container.getInput().filters,
queryFilter.getFilters(),
filterManager.getFilters(),
esFilters.COMPARE_ALL_OPTIONS
)
) {
// Add filters modifies the object passed to it, hence the clone deep.
queryFilter.addFilters(_.cloneDeep(container.getInput().filters));
filterManager.addFilters(_.cloneDeep(container.getInput().filters));

dashboardStateManager.applyFilters(
$scope.model.query,
Expand Down Expand Up @@ -487,13 +493,8 @@ export class DashboardAppController {
});

dashboardStateManager.applyFilters(
dashboardStateManager.getQuery() || {
query: '',
language:
localStorage.get('kibana.userQueryLanguage') ||
uiSettings.get(UI_SETTINGS.SEARCH_QUERY_LANGUAGE),
},
queryFilter.getFilters()
dashboardStateManager.getQuery() || queryStringManager.getDefaultQuery(),
filterManager.getFilters()
);

timefilter.disableTimeRangeSelector();
Expand Down Expand Up @@ -567,21 +568,13 @@ export class DashboardAppController {
}
};

$scope.updateQueryAndFetch = function ({ query, dateRange }) {
if (dateRange) {
timefilter.setTime(dateRange);
}

const oldQuery = $scope.model.query;
if (_.isEqual(oldQuery, query)) {
$scope.handleRefresh = function (_payload, isUpdate) {
if (isUpdate === false) {
// The user can still request a reload in the query bar, even if the
// query is the same, and in that case, we have to explicitly ask for
// a reload, since no state changes will cause it.
lastReloadRequestTime = new Date().getTime();
refreshDashboardContainer();
} else {
$scope.model.query = query;
dashboardStateManager.applyFilters($scope.model.query, $scope.model.filters);
}
};

Expand All @@ -600,7 +593,7 @@ export class DashboardAppController {
// Making this method sync broke the updates.
// Temporary fix, until we fix the complex state in this file.
setTimeout(() => {
queryFilter.setFilters(allFilters);
filterManager.setFilters(allFilters);
}, 0);
};

Expand Down Expand Up @@ -633,11 +626,6 @@ export class DashboardAppController {

$scope.indexPatterns = [];

$scope.$watch('model.query', (newQuery: Query) => {
const query = migrateLegacyQuery(newQuery) as Query;
$scope.updateQueryAndFetch({ query });
});

$scope.$watch(
() => dashboardCapabilities.saveQuery,
(newCapability) => {
Expand Down Expand Up @@ -678,18 +666,11 @@ export class DashboardAppController {
showFilterBar,
indexPatterns: $scope.indexPatterns,
showSaveQuery: $scope.showSaveQuery,
query: $scope.model.query,
savedQuery: $scope.savedQuery,
onSavedQueryIdChange,
savedQueryId: dashboardStateManager.getSavedQueryId(),
useDefaultBehaviors: true,
onQuerySubmit: (payload: { dateRange: TimeRange; query?: Query }): void => {
if (!payload.query) {
$scope.updateQueryAndFetch({ query: $scope.model.query, dateRange: payload.dateRange });
} else {
$scope.updateQueryAndFetch({ query: payload.query, dateRange: payload.dateRange });
}
},
onQuerySubmit: $scope.handleRefresh,
};
};
const dashboardNavBar = document.getElementById('dashboardChrome');
Expand All @@ -704,25 +685,11 @@ export class DashboardAppController {
};

$scope.timefilterSubscriptions$ = new Subscription();

const timeChanges$ = merge(timefilter.getRefreshIntervalUpdate$(), timefilter.getTimeUpdate$());
$scope.timefilterSubscriptions$.add(
subscribeWithScope(
$scope,
timefilter.getRefreshIntervalUpdate$(),
{
next: () => {
updateState();
refreshDashboardContainer();
},
},
(error: AngularHttpError | Error | string) => addFatalError(fatalErrors, error)
)
);

$scope.timefilterSubscriptions$.add(
subscribeWithScope(
$scope,
timefilter.getTimeUpdate$(),
timeChanges$,
{
next: () => {
updateState();
Expand Down Expand Up @@ -1095,13 +1062,21 @@ export class DashboardAppController {

updateViewMode(dashboardStateManager.getViewMode());

const filterChanges = merge(filterManager.getUpdates$(), queryStringManager.getUpdates$()).pipe(
debounceTime(100)
);

// update root source when filters update
const updateSubscription = queryFilter.getUpdates$().subscribe({
const updateSubscription = filterChanges.subscribe({
next: () => {
$scope.model.filters = queryFilter.getFilters();
$scope.model.filters = filterManager.getFilters();
$scope.model.query = queryStringManager.getQuery();
dashboardStateManager.applyFilters($scope.model.query, $scope.model.filters);
if (dashboardContainer) {
dashboardContainer.updateInput({ filters: $scope.model.filters });
dashboardContainer.updateInput({
filters: $scope.model.filters,
query: $scope.model.query,
});
}
},
});
Expand Down
9 changes: 6 additions & 3 deletions src/plugins/data/public/public.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -199,10 +199,11 @@ export const castEsToKbnFieldTypeName: (esType: ES_FIELD_TYPES | string) => KBN_
// Warning: (ae-missing-release-tag) "connectToQueryState" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public
export const connectToQueryState: <S extends QueryState>({ timefilter: { timefilter }, filterManager, state$, }: Pick<QueryStart | QuerySetup, 'timefilter' | 'filterManager' | 'state$'>, stateContainer: BaseStateContainer<S>, syncConfig: {
export const connectToQueryState: <S extends QueryState>({ timefilter: { timefilter }, filterManager, queryString, state$, }: Pick<QueryStart | QuerySetup, 'timefilter' | 'filterManager' | 'queryString' | 'state$'>, stateContainer: BaseStateContainer<S>, syncConfig: {
time?: boolean;
refreshInterval?: boolean;
filters?: FilterStateStore | boolean;
query?: boolean;
}) => () => void;

// Warning: (ae-missing-release-tag) "createSavedQueryService" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
Expand Down Expand Up @@ -1397,6 +1398,8 @@ export interface QueryState {
// (undocumented)
filters?: Filter[];
// (undocumented)
query?: Query;
// (undocumented)
refreshInterval?: RefreshInterval;
// (undocumented)
time?: TimeRange;
Expand Down Expand Up @@ -1771,7 +1774,7 @@ export type StatefulSearchBarProps = SearchBarOwnProps & {
// Warning: (ae-missing-release-tag) "syncQueryStateWithUrl" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public
export const syncQueryStateWithUrl: (query: Pick<QueryStart | QuerySetup, 'filterManager' | 'timefilter' | 'state$'>, kbnUrlStateStorage: IKbnUrlStateStorage) => {
export const syncQueryStateWithUrl: (query: Pick<QueryStart | QuerySetup, 'filterManager' | 'timefilter' | 'queryString' | 'state$'>, kbnUrlStateStorage: IKbnUrlStateStorage) => {
stop: () => void;
hasInheritedQueryFromUrl: boolean;
};
Expand Down Expand Up @@ -1919,7 +1922,7 @@ export const UI_SETTINGS: {
// src/plugins/data/public/index.ts:391:1 - (ae-forgotten-export) The symbol "parseInterval" needs to be exported by the entry point index.d.ts
// src/plugins/data/public/index.ts:392:1 - (ae-forgotten-export) The symbol "propFilter" needs to be exported by the entry point index.d.ts
// src/plugins/data/public/index.ts:395:1 - (ae-forgotten-export) The symbol "toAbsoluteDates" needs to be exported by the entry point index.d.ts
// src/plugins/data/public/query/state_sync/connect_to_query_state.ts:41:60 - (ae-forgotten-export) The symbol "FilterStateStore" needs to be exported by the entry point index.d.ts
// src/plugins/data/public/query/state_sync/connect_to_query_state.ts:45:5 - (ae-forgotten-export) The symbol "FilterStateStore" needs to be exported by the entry point index.d.ts
// src/plugins/data/public/types.ts:54:5 - (ae-forgotten-export) The symbol "createFiltersFromValueClickAction" needs to be exported by the entry point index.d.ts
// src/plugins/data/public/types.ts:55:5 - (ae-forgotten-export) The symbol "createFiltersFromRangeSelectAction" needs to be exported by the entry point index.d.ts
// src/plugins/data/public/types.ts:63:5 - (ae-forgotten-export) The symbol "IndexPatternSelectProps" needs to be exported by the entry point index.d.ts
Expand Down
Loading