Skip to content

Commit

Permalink
Add refreshConfig to embeddable container state (#31611) (#31959)
Browse files Browse the repository at this point in the history
* Add refreshConfig to embeddable container state

* TS fun
  • Loading branch information
nreese authored Feb 25, 2019
1 parent d1acfe5 commit 7489374
Show file tree
Hide file tree
Showing 10 changed files with 73 additions and 25 deletions.
38 changes: 19 additions & 19 deletions src/legacy/core_plugins/kibana/public/dashboard/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,19 +17,19 @@ A high level walk through of types of dashboard state and how dashboard and
separation because it allows us to force some consistency in our UX. For example, we may
not want a visualization to all of a sudden go from supporting drilldown links to
not supporting it, as it would mean disappearing panel context menu items.
**Embeddable state** - Data the embeddable gives the dashboard throughout it's lifecycle as

**Embeddable state** - Data the embeddable gives the dashboard throughout it's lifecycle as
things update and the user interacts with it. This is communicated to the dashboard via the
function `onEmbeddableStateChanged` that is passed in to the `EmbeddableFactory.create` call.

**Container state** - Data the dashboard gives to the embeddable throughout it's lifecycle
as things update and the user interacts with Kibana. This is communicated to the embeddable via
the function `onContainerStateChanged` which is returned from the `EmbeddableFactory.create` call

**Container metadata** - State that only needs to be given to the embeddable once,
**Container metadata** - State that only needs to be given to the embeddable once,
and does not change thereafter. This will contain data given to dashboard when a new embeddable is
added to a dashboard. Currently, this is really only the saved object id.

**Dashboard storage data** - Data persisted in elasticsearch. Should not be coupled to the redux tree.

**Dashboard redux tree** - State stored in the dashboard redux tree.
Expand All @@ -38,9 +38,9 @@ A high level walk through of types of dashboard state and how dashboard and
I'm not sure if *any* data belongs here but we talked about it, so keeping it in here. We thought initially
it could be supportsDrillDowns but for type visualizations, for example, this depends on the visualization
"subtype" (e.g. input controls vs line chart).



### Dashboard/Embeddable communication psuedocode
```js
dashboard_panel.js:
Expand All @@ -59,19 +59,19 @@ class EmbeddableViewport extends Component {
}
}
}

componentWillUnmount() {
this.embeddable.destroy();
}

// We let react/redux tell us when to tell the embeddable that some container
// state changed.
componentDidUpdate(prevProps) {
if (this.embeddable && !_.isEqual(prevProps.containerState, this.props.containerState)) {
this.embeddable.onContainerStateChanged(this.props.containerState);
}
}

render() {
return (
<div>
Expand Down Expand Up @@ -106,7 +106,7 @@ State communicated to the embeddable.
embeddableCustomization: Object,
hidePanelTitles: boolean,
title: string,

// TODO:
filters: FilterObject,
timeRange: TimeRangeObject,
Expand All @@ -124,21 +124,21 @@ State communicated to the embeddable.
### Embeddable Metadata
```
{
{
// Index patterns used by this embeddable. This information is currently
// used by the filter on a dashboard for which fields to show in the
// dropdown. Otherwise we'd have to show all fields over all indexes and
// if no embeddables use those index patterns, there really is no point
// to filtering on them.
indexPatterns: Array.<IndexPatterns>,

// Dashboard navigates to this url when the user clicks 'Edit visualization'
// in the panel context menu.
editUrl: string,

// Title to be shown in the panel. Can be overridden at the panel level.
title: string,

// TODO:
// If this is true, then dashboard will show a "configure drill down
// links" menu option in the context menu for the panel.
Expand All @@ -156,12 +156,12 @@ Embeddable state is the data that the embeddable gives dashboard when something
// If a filter action was initiated by a user action (e.g. clicking on a bar chart)
// This is how dashboard will know and update itself to match.
stagedFilters: FilterObject,
// TODO: More possible options to go in here:


// TODO: More possible options to go in here:
error: Error,
isLoading: boolean,
renderComplete: boolean,
renderComplete: boolean,
appliedtimeRange: TimeRangeObject,
stagedTimeRange: TimeRangeObject,
// This information will need to be exposed so other plugins (e.g. ML)
Expand Down
10 changes: 9 additions & 1 deletion src/legacy/core_plugins/kibana/public/dashboard/actions/view.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
*/

import { createAction } from 'redux-actions';
import { Filters, Query, TimeRange } from 'ui/embeddable';
import { Filters, Query, RefreshConfig, TimeRange } from 'ui/embeddable';
import { KibanaAction } from '../../selectors/types';
import { DashboardViewMode } from '../dashboard_view_mode';
import { PanelId } from '../selectors';
Expand All @@ -32,6 +32,7 @@ export enum ViewActionTypeKeys {
UPDATE_USE_MARGINS = 'UPDATE_USE_MARGINS',
UPDATE_HIDE_PANEL_TITLES = 'UPDATE_HIDE_PANEL_TITLES',
UPDATE_TIME_RANGE = 'UPDATE_TIME_RANGE',
UPDATE_REFRESH_CONFIG = 'UPDATE_REFRESH_CONFIG',
UPDATE_FILTERS = 'UPDATE_FILTERS',
UPDATE_QUERY = 'UPDATE_QUERY',
CLOSE_CONTEXT_MENU = 'CLOSE_CONTEXT_MENU',
Expand Down Expand Up @@ -64,6 +65,9 @@ export interface UpdateHidePanelTitlesAction
export interface UpdateTimeRangeAction
extends KibanaAction<ViewActionTypeKeys.UPDATE_TIME_RANGE, TimeRange> {}

export interface UpdateRefreshConfigAction
extends KibanaAction<ViewActionTypeKeys.UPDATE_REFRESH_CONFIG, RefreshConfig> {}

export interface UpdateFiltersAction
extends KibanaAction<ViewActionTypeKeys.UPDATE_FILTERS, Filters> {}

Expand All @@ -79,6 +83,7 @@ export type ViewActions =
| UpdateUseMarginsAction
| UpdateHidePanelTitlesAction
| UpdateTimeRangeAction
| UpdateRefreshConfigAction
| UpdateFiltersAction
| UpdateQueryAction;

Expand All @@ -97,5 +102,8 @@ export const updateHidePanelTitles = createAction<boolean>(
ViewActionTypeKeys.UPDATE_HIDE_PANEL_TITLES
);
export const updateTimeRange = createAction<TimeRange>(ViewActionTypeKeys.UPDATE_TIME_RANGE);
export const updateRefreshConfig = createAction<RefreshConfig>(
ViewActionTypeKeys.UPDATE_REFRESH_CONFIG
);
export const updateFilters = createAction<Filters>(ViewActionTypeKeys.UPDATE_FILTERS);
export const updateQuery = createAction<Query>(ViewActionTypeKeys.UPDATE_QUERY);
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,7 @@ app.directive('dashboardApp', function ($injector) {
courier.fetch();
};
dashboardStateManager.handleTimeChange(timefilter.getTime());
dashboardStateManager.handleRefreshConfigChange(timefilter.getRefreshInterval());

$scope.expandedPanel = null;
$scope.dashboardViewMode = dashboardStateManager.getViewMode();
Expand Down Expand Up @@ -291,7 +292,10 @@ app.directive('dashboardApp', function ($injector) {
// directly passed down time filter. Then we can get rid of this reliance on scope broadcasts.
$scope.refresh();
});
$scope.$listenAndDigestAsync(timefilter, 'refreshIntervalUpdate', updateState);
$scope.$listenAndDigestAsync(timefilter, 'refreshIntervalUpdate', () => {
dashboardStateManager.handleRefreshConfigChange(timefilter.getRefreshInterval());
updateState();
});
$scope.$listenAndDigestAsync(timefilter, 'timeUpdate', updateState);

function updateViewMode(newMode) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import {
updateDescription,
updateHidePanelTitles,
updateTimeRange,
updateRefreshConfig,
clearStagedFilters,
updateFilters,
updateQuery,
Expand Down Expand Up @@ -151,6 +152,13 @@ export class DashboardStateManager {
}));
}

handleRefreshConfigChange({ pause, value }) {
store.dispatch(updateRefreshConfig({
isPaused: pause,
interval: value,
}));
}

/**
* Changes made to app state outside of direct calls to this class will need to be propagated to the store.
* @private
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,7 @@ DashboardPanelUi.propTypes = {
destroy: PropTypes.func.isRequired,
containerState: PropTypes.shape({
timeRange: PropTypes.object,
refreshConfig: PropTypes.object,
filters: PropTypes.array,
query: PropTypes.object,
embeddableCustomization: PropTypes.object,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import { cloneDeep } from 'lodash';
import { Reducer } from 'redux';
import { ViewActions, ViewActionTypeKeys } from '../actions';

import { Filters, Query, TimeRange } from 'ui/embeddable';
import { Filters, Query, RefreshConfig, TimeRange } from 'ui/embeddable';
import { QueryLanguageType } from 'ui/embeddable/types';
import { DashboardViewMode } from '../dashboard_view_mode';
import { PanelId, ViewState } from '../selectors';
Expand Down Expand Up @@ -61,6 +61,11 @@ const updateTimeRange = (view: ViewState, timeRange: TimeRange) => ({
timeRange,
});

const updateRefreshConfig = (view: ViewState, refreshConfig: RefreshConfig) => ({
...view,
refreshConfig,
});

const updateFilters = (view: ViewState, filters: Filters) => ({
...view,
filters: cloneDeep(filters),
Expand Down Expand Up @@ -88,6 +93,7 @@ export const viewReducer: Reducer<ViewState> = (
isFullScreenMode: false,
query: { language: QueryLanguageType.LUCENE, query: '' },
timeRange: { to: 'now', from: 'now-15m' },
refreshConfig: { isPaused: true, interval: 0 },
useMargins: true,
viewMode: DashboardViewMode.VIEW,
},
Expand All @@ -106,6 +112,8 @@ export const viewReducer: Reducer<ViewState> = (
return updateHidePanelTitles(view, action.payload);
case ViewActionTypeKeys.UPDATE_TIME_RANGE:
return updateTimeRange(view, action.payload);
case ViewActionTypeKeys.UPDATE_REFRESH_CONFIG:
return updateRefreshConfig(view, action.payload);
case ViewActionTypeKeys.UPDATE_USE_MARGINS:
return updateUseMargins(view, action.payload);
case ViewActionTypeKeys.UPDATE_VIEW_MODE:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,14 @@
*/

import _ from 'lodash';
import { ContainerState, EmbeddableMetadata, Filters, Query, TimeRange } from 'ui/embeddable';
import {
ContainerState,
EmbeddableMetadata,
Filters,
Query,
RefreshConfig,
TimeRange,
} from 'ui/embeddable';
import { EmbeddableCustomization } from 'ui/embeddable/types';
import { DashboardViewMode } from '../dashboard_view_mode';
import {
Expand Down Expand Up @@ -108,6 +115,9 @@ export const getMaximizedPanelId = (dashboard: DashboardState): PanelId | undefi

export const getTimeRange = (dashboard: DashboardState): TimeRange => dashboard.view.timeRange;

export const getRefreshConfig = (dashboard: DashboardState): RefreshConfig =>
dashboard.view.refreshConfig;

export const getFilters = (dashboard: DashboardState): Filters => dashboard.view.filters;

export const getQuery = (dashboard: DashboardState): Query => dashboard.view.query;
Expand All @@ -132,6 +142,7 @@ export const getContainerState = (dashboard: DashboardState, panelId: PanelId):
from: time.from,
to: time.to,
},
refreshConfig: getRefreshConfig(dashboard),
viewMode: getViewMode(dashboard),
};
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
* under the License.
*/

import { EmbeddableMetadata, Filters, Query, TimeRange } from 'ui/embeddable';
import { EmbeddableMetadata, Filters, Query, RefreshConfig, TimeRange } from 'ui/embeddable';
import { DashboardViewMode } from '../dashboard_view_mode';

export interface ViewState {
Expand All @@ -26,6 +26,7 @@ export interface ViewState {
readonly maximizedPanelId?: string;
readonly visibleContextMenuPanelId?: string;
readonly timeRange: TimeRange;
readonly refreshConfig: RefreshConfig;
readonly hidePanelTitles: boolean;
readonly useMargins: boolean;
readonly query: Query;
Expand Down
2 changes: 1 addition & 1 deletion src/legacy/ui/public/embeddable/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,4 @@ export { EmbeddableFactory, OnEmbeddableStateChanged } from './embeddable_factor
export * from './embeddable';
export * from './context_menu_actions';
export { EmbeddableFactoriesRegistryProvider } from './embeddable_factories_registry';
export { ContainerState, EmbeddableState, Query, Filters, TimeRange } from './types';
export { ContainerState, EmbeddableState, Query, Filters, TimeRange, RefreshConfig } from './types';
7 changes: 7 additions & 0 deletions src/legacy/ui/public/embeddable/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@ export interface TimeRange {
from: string;
}

export interface RefreshConfig {
isPaused: boolean;
interval: number;
}

export interface FilterMeta {
disabled: boolean;
}
Expand Down Expand Up @@ -55,6 +60,8 @@ export interface ContainerState {

filters: Filters;

refreshConfig: RefreshConfig;

query: Query;

// The shape will be up to the embeddable type.
Expand Down

0 comments on commit 7489374

Please sign in to comment.