mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 01:38:56 -04:00
Typescriptify dashboard redux code (#19857)
* Typescriptify dashboard redux code * Address code review comments * minor fixes * move all type dependencies to dev
This commit is contained in:
parent
fbbd5c111e
commit
26da49e129
41 changed files with 1325 additions and 879 deletions
|
@ -86,7 +86,6 @@
|
|||
"@kbn/pm": "link:packages/kbn-pm",
|
||||
"@kbn/test-subj-selector": "link:packages/kbn-test-subj-selector",
|
||||
"@kbn/ui-framework": "link:packages/kbn-ui-framework",
|
||||
"@types/prop-types": "^15.5.3",
|
||||
"JSONStream": "1.1.1",
|
||||
"accept-language-parser": "1.2.0",
|
||||
"angular": "1.6.9",
|
||||
|
@ -231,10 +230,15 @@
|
|||
"@types/execa": "^0.9.0",
|
||||
"@types/getopts": "^2.0.0",
|
||||
"@types/glob": "^5.0.35",
|
||||
"@types/jest": "^22.2.3",
|
||||
"@types/listr": "^0.13.0",
|
||||
"@types/lodash": "^3.10.1",
|
||||
"@types/minimatch": "^2.0.29",
|
||||
"@types/prop-types": "^15.5.3",
|
||||
"@types/react": "^16.3.14",
|
||||
"@types/react-dom": "^16.0.5",
|
||||
"@types/redux": "^3.6.31",
|
||||
"@types/redux-actions": "^2.2.1",
|
||||
"angular-mocks": "1.4.7",
|
||||
"babel-eslint": "8.1.2",
|
||||
"babel-jest": "^22.4.3",
|
||||
|
|
|
@ -1,60 +0,0 @@
|
|||
/*
|
||||
* 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 { createAction } from 'redux-actions';
|
||||
import _ from 'lodash';
|
||||
|
||||
import {
|
||||
updatePanel
|
||||
} from './panels';
|
||||
|
||||
import {
|
||||
getPanel,
|
||||
getEmbeddableCustomization,
|
||||
} from '../../selectors/dashboard_selectors';
|
||||
|
||||
export const embeddableIsInitializing = createAction('EMBEDDABLE_IS_INITIALIZING');
|
||||
export const embeddableIsInitialized = createAction('EMBEDDABLE_INITIALIZED');
|
||||
export const setStagedFilter = createAction('SET_STAGED_FILTER');
|
||||
export const clearStagedFilters = createAction('CLEAR_STAGED_FILTERS');
|
||||
export const embeddableError = createAction('EMBEDDABLE_ERROR');
|
||||
|
||||
/**
|
||||
* The main point of communication from the embeddable to the dashboard. Any time state in the embeddable
|
||||
* changes, this function will be called. The data is then extracted from EmbeddableState and stored in
|
||||
* redux so the appropriate actions are taken and UI updated.
|
||||
|
||||
* @param {string} panelId - the id of the panel whose state has changed.
|
||||
* @param {EmbeddableState} embeddableState - the new state of the embeddable.
|
||||
*/
|
||||
export function embeddableStateChanged({ panelId, embeddableState }) {
|
||||
return (dispatch, getState) => {
|
||||
// Translate embeddableState to things redux cares about.
|
||||
const customization = getEmbeddableCustomization(getState(), panelId);
|
||||
if (!_.isEqual(embeddableState.customization, customization)) {
|
||||
const panel = getPanel(getState(), panelId);
|
||||
dispatch(updatePanel({ ...panel, embeddableConfig: _.cloneDeep(embeddableState.customization) }));
|
||||
}
|
||||
|
||||
if (embeddableState.stagedFilter) {
|
||||
dispatch(setStagedFilter({ stagedFilter: embeddableState.stagedFilter, panelId }));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
@ -20,14 +20,12 @@
|
|||
import { store } from '../../store';
|
||||
import {
|
||||
clearStagedFilters,
|
||||
setStagedFilter,
|
||||
embeddableIsInitialized,
|
||||
embeddableIsInitializing,
|
||||
setStagedFilter,
|
||||
} from '../actions';
|
||||
|
||||
import {
|
||||
getStagedFilters,
|
||||
} from '../../selectors';
|
||||
import { getStagedFilters } from '../../selectors';
|
||||
|
||||
beforeAll(() => {
|
||||
store.dispatch(embeddableIsInitializing('foo1'));
|
||||
|
@ -43,13 +41,17 @@ describe('staged filters', () => {
|
|||
});
|
||||
|
||||
test('can set a staged filter', () => {
|
||||
store.dispatch(setStagedFilter({ stagedFilter: ['imafilter'], panelId: 'foo1' }));
|
||||
store.dispatch(
|
||||
setStagedFilter({ stagedFilter: ['imafilter'], panelId: 'foo1' })
|
||||
);
|
||||
const stagedFilters = getStagedFilters(store.getState());
|
||||
expect(stagedFilters.length).toBe(1);
|
||||
});
|
||||
|
||||
test('getStagedFilters returns filters for all embeddables', () => {
|
||||
store.dispatch(setStagedFilter({ stagedFilter: ['imafilter'], panelId: 'foo2' }));
|
||||
store.dispatch(
|
||||
setStagedFilter({ stagedFilter: ['imafilter'], panelId: 'foo2' })
|
||||
);
|
||||
const stagedFilters = getStagedFilters(store.getState());
|
||||
expect(stagedFilters.length).toBe(2);
|
||||
});
|
||||
|
@ -60,4 +62,3 @@ describe('staged filters', () => {
|
|||
expect(stagedFilters.length).toBe(0);
|
||||
});
|
||||
});
|
||||
|
144
src/core_plugins/kibana/public/dashboard/actions/embeddables.ts
Normal file
144
src/core_plugins/kibana/public/dashboard/actions/embeddables.ts
Normal file
|
@ -0,0 +1,144 @@
|
|||
/*
|
||||
* 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 _ from 'lodash';
|
||||
import { Dispatch } from 'redux';
|
||||
import { createAction } from 'redux-actions';
|
||||
import {
|
||||
CoreKibanaState,
|
||||
getEmbeddableCustomization,
|
||||
getPanel,
|
||||
} from '../../selectors';
|
||||
import { PanelId, PanelState } from '../selectors';
|
||||
import { updatePanel } from './panels';
|
||||
|
||||
import { EmbeddableMetadata, EmbeddableState } from 'ui/embeddable';
|
||||
import { KibanaAction } from '../../selectors/types';
|
||||
|
||||
export enum EmbeddableActionTypeKeys {
|
||||
EMBEDDABLE_IS_INITIALIZING = 'EMBEDDABLE_IS_INITIALIZING',
|
||||
EMBEDDABLE_IS_INITIALIZED = 'EMBEDDABLE_IS_INITIALIZED',
|
||||
SET_STAGED_FILTER = 'SET_STAGED_FILTER',
|
||||
CLEAR_STAGED_FILTERS = 'CLEAR_STAGED_FILTERS',
|
||||
EMBEDDABLE_ERROR = 'EMBEDDABLE_ERROR',
|
||||
}
|
||||
|
||||
export interface EmbeddableIsInitializingAction
|
||||
extends KibanaAction<
|
||||
EmbeddableActionTypeKeys.EMBEDDABLE_IS_INITIALIZING,
|
||||
PanelId
|
||||
> {}
|
||||
|
||||
export interface EmbeddableIsInitializedActionPayload {
|
||||
panelId: PanelId;
|
||||
metadata: EmbeddableMetadata;
|
||||
}
|
||||
|
||||
export interface EmbeddableIsInitializedAction
|
||||
extends KibanaAction<
|
||||
EmbeddableActionTypeKeys.EMBEDDABLE_IS_INITIALIZED,
|
||||
EmbeddableIsInitializedActionPayload
|
||||
> {}
|
||||
|
||||
export interface SetStagedFilterActionPayload {
|
||||
panelId: PanelId;
|
||||
stagedFilter: object;
|
||||
}
|
||||
|
||||
export interface SetStagedFilterAction
|
||||
extends KibanaAction<
|
||||
EmbeddableActionTypeKeys.SET_STAGED_FILTER,
|
||||
SetStagedFilterActionPayload
|
||||
> {}
|
||||
|
||||
export interface ClearStagedFiltersAction
|
||||
extends KibanaAction<
|
||||
EmbeddableActionTypeKeys.CLEAR_STAGED_FILTERS,
|
||||
undefined
|
||||
> {}
|
||||
|
||||
export interface EmbeddableErrorActionPayload {
|
||||
error: string | object;
|
||||
panelId: PanelId;
|
||||
}
|
||||
|
||||
export interface EmbeddableErrorAction
|
||||
extends KibanaAction<
|
||||
EmbeddableActionTypeKeys.EMBEDDABLE_ERROR,
|
||||
EmbeddableErrorActionPayload
|
||||
> {}
|
||||
|
||||
export type EmbeddableActions =
|
||||
| EmbeddableIsInitializingAction
|
||||
| EmbeddableIsInitializedAction
|
||||
| ClearStagedFiltersAction
|
||||
| SetStagedFilterAction
|
||||
| EmbeddableErrorAction;
|
||||
|
||||
export const embeddableIsInitializing = createAction<PanelId>(
|
||||
EmbeddableActionTypeKeys.EMBEDDABLE_IS_INITIALIZING
|
||||
);
|
||||
export const embeddableIsInitialized = createAction<
|
||||
EmbeddableIsInitializedActionPayload
|
||||
>(EmbeddableActionTypeKeys.EMBEDDABLE_IS_INITIALIZED);
|
||||
export const setStagedFilter = createAction<SetStagedFilterActionPayload>(
|
||||
EmbeddableActionTypeKeys.SET_STAGED_FILTER
|
||||
);
|
||||
export const clearStagedFilters = createAction(
|
||||
EmbeddableActionTypeKeys.CLEAR_STAGED_FILTERS
|
||||
);
|
||||
export const embeddableError = createAction<EmbeddableErrorActionPayload>(
|
||||
EmbeddableActionTypeKeys.EMBEDDABLE_ERROR
|
||||
);
|
||||
|
||||
/**
|
||||
* The main point of communication from the embeddable to the dashboard. Any time state in the embeddable
|
||||
* changes, this function will be called. The data is then extracted from EmbeddableState and stored in
|
||||
* redux so the appropriate actions are taken and UI updated.
|
||||
*
|
||||
* @param changeData.panelId - the id of the panel whose state has changed.
|
||||
* @param changeData.embeddableState - the new state of the embeddable.
|
||||
*/
|
||||
export function embeddableStateChanged(changeData: {
|
||||
panelId: PanelId;
|
||||
embeddableState: EmbeddableState;
|
||||
}) {
|
||||
const { panelId, embeddableState } = changeData;
|
||||
return (
|
||||
dispatch: Dispatch<CoreKibanaState>,
|
||||
getState: () => CoreKibanaState
|
||||
) => {
|
||||
// Translate embeddableState to things redux cares about.
|
||||
const customization = getEmbeddableCustomization(getState(), panelId);
|
||||
if (!_.isEqual(embeddableState.customization, customization)) {
|
||||
const originalPanelState = getPanel(getState(), panelId);
|
||||
const newPanelState: PanelState = {
|
||||
...originalPanelState,
|
||||
embeddableConfig: _.cloneDeep(embeddableState.customization),
|
||||
};
|
||||
dispatch(updatePanel(newPanelState));
|
||||
}
|
||||
|
||||
if (embeddableState.stagedFilter) {
|
||||
dispatch(
|
||||
setStagedFilter({ stagedFilter: embeddableState.stagedFilter, panelId })
|
||||
);
|
||||
}
|
||||
};
|
||||
}
|
|
@ -20,8 +20,4 @@
|
|||
export * from './view';
|
||||
export * from './panels';
|
||||
export * from './embeddables';
|
||||
|
||||
export {
|
||||
updateDescription,
|
||||
updateTitle,
|
||||
} from './metadata';
|
||||
export * from './metadata';
|
51
src/core_plugins/kibana/public/dashboard/actions/metadata.ts
Normal file
51
src/core_plugins/kibana/public/dashboard/actions/metadata.ts
Normal file
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
* 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 { createAction } from 'redux-actions';
|
||||
import { KibanaAction } from '../../selectors/types';
|
||||
|
||||
export enum MetadataActionTypeKeys {
|
||||
UPDATE_DESCRIPTION = 'UPDATE_DESCRIPTION',
|
||||
UPDATE_TITLE = 'UPDATE_TITLE',
|
||||
}
|
||||
|
||||
export type UpdateTitleActionPayload = string;
|
||||
|
||||
export interface UpdateTitleAction
|
||||
extends KibanaAction<
|
||||
MetadataActionTypeKeys.UPDATE_TITLE,
|
||||
UpdateTitleActionPayload
|
||||
> {}
|
||||
|
||||
export type UpdateDescriptionActionPayload = string;
|
||||
|
||||
export interface UpdateDescriptionAction
|
||||
extends KibanaAction<
|
||||
MetadataActionTypeKeys.UPDATE_DESCRIPTION,
|
||||
UpdateDescriptionActionPayload
|
||||
> {}
|
||||
|
||||
export type MetadataActions = UpdateDescriptionAction | UpdateTitleAction;
|
||||
|
||||
export const updateDescription = createAction<UpdateDescriptionAction>(
|
||||
MetadataActionTypeKeys.UPDATE_DESCRIPTION
|
||||
);
|
||||
export const updateTitle = createAction<UpdateTitleAction>(
|
||||
MetadataActionTypeKeys.UPDATE_TITLE
|
||||
);
|
|
@ -1,43 +0,0 @@
|
|||
/*
|
||||
* 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 { createAction } from 'redux-actions';
|
||||
|
||||
export const deletePanel = createAction('DELETE_PANEL');
|
||||
export const updatePanel = createAction('UPDATE_PANEL');
|
||||
export const resetPanelTitle = createAction('RESET_PANEl_TITLE');
|
||||
export const setPanelTitle = createAction('SET_PANEl_TITLE',
|
||||
/**
|
||||
* @param title {string}
|
||||
* @param panelIndex {string}
|
||||
*/
|
||||
(title, panelIndex) => ({ title, panelIndex })
|
||||
);
|
||||
|
||||
/**
|
||||
* @param panels {Array<PanelState>}
|
||||
* @return {Object}
|
||||
*/
|
||||
export const updatePanels = createAction('UPDATE_PANELS');
|
||||
|
||||
/**
|
||||
* @param panels {Array<PanelState>}
|
||||
* @return {Object}
|
||||
*/
|
||||
export const setPanels = createAction('SET_PANELS');
|
84
src/core_plugins/kibana/public/dashboard/actions/panels.ts
Normal file
84
src/core_plugins/kibana/public/dashboard/actions/panels.ts
Normal file
|
@ -0,0 +1,84 @@
|
|||
/*
|
||||
* 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 { createAction } from 'redux-actions';
|
||||
import { KibanaAction } from '../../selectors/types';
|
||||
import { PanelId, PanelsMap, PanelState } from '../selectors';
|
||||
|
||||
export enum PanelActionTypeKeys {
|
||||
DELETE_PANEL = 'DELETE_PANEL',
|
||||
UPDATE_PANEL = 'UPDATE_PANEL',
|
||||
RESET_PANEl_TITLE = 'RESET_PANEl_TITLE',
|
||||
SET_PANEl_TITLE = 'SET_PANEl_TITLE',
|
||||
UPDATE_PANELS = 'UPDATE_PANELS',
|
||||
SET_PANELS = 'SET_PANELS',
|
||||
}
|
||||
|
||||
export interface DeletePanelAction
|
||||
extends KibanaAction<PanelActionTypeKeys.DELETE_PANEL, PanelId> {}
|
||||
|
||||
export interface UpdatePanelAction
|
||||
extends KibanaAction<PanelActionTypeKeys.UPDATE_PANEL, PanelState> {}
|
||||
|
||||
export interface UpdatePanelsAction
|
||||
extends KibanaAction<PanelActionTypeKeys.UPDATE_PANELS, PanelsMap> {}
|
||||
|
||||
export interface ResetPanelTitleAction
|
||||
extends KibanaAction<PanelActionTypeKeys.RESET_PANEl_TITLE, PanelId> {}
|
||||
|
||||
export interface SetPanelTitleActionPayload {
|
||||
panelId: PanelId;
|
||||
title: string;
|
||||
}
|
||||
|
||||
export interface SetPanelTitleAction
|
||||
extends KibanaAction<
|
||||
PanelActionTypeKeys.SET_PANEl_TITLE,
|
||||
SetPanelTitleActionPayload
|
||||
> {}
|
||||
|
||||
export interface SetPanelsAction
|
||||
extends KibanaAction<PanelActionTypeKeys.SET_PANELS, PanelsMap> {}
|
||||
|
||||
export type PanelActions =
|
||||
| DeletePanelAction
|
||||
| UpdatePanelAction
|
||||
| ResetPanelTitleAction
|
||||
| UpdatePanelsAction
|
||||
| SetPanelTitleAction
|
||||
| SetPanelsAction;
|
||||
|
||||
export const deletePanel = createAction<PanelId>(
|
||||
PanelActionTypeKeys.DELETE_PANEL
|
||||
);
|
||||
export const updatePanel = createAction<PanelState>(
|
||||
PanelActionTypeKeys.UPDATE_PANEL
|
||||
);
|
||||
export const resetPanelTitle = createAction<PanelId>(
|
||||
PanelActionTypeKeys.RESET_PANEl_TITLE
|
||||
);
|
||||
export const setPanelTitle = createAction<SetPanelTitleActionPayload>(
|
||||
PanelActionTypeKeys.SET_PANEl_TITLE
|
||||
);
|
||||
export const updatePanels = createAction<PanelsMap>(
|
||||
PanelActionTypeKeys.UPDATE_PANELS
|
||||
);
|
||||
export const setPanels = createAction<PanelsMap>(
|
||||
PanelActionTypeKeys.SET_PANELS
|
||||
);
|
|
@ -1,31 +0,0 @@
|
|||
/*
|
||||
* 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 { createAction } from 'redux-actions';
|
||||
|
||||
export const updateViewMode = createAction('UPDATE_VIEW_MODE');
|
||||
export const setVisibleContextMenuPanelId = createAction('SET_VISIBLE_CONTEXT_MENU_PANEL_ID');
|
||||
export const maximizePanel = createAction('MAXIMIZE_PANEl');
|
||||
export const minimizePanel = createAction('MINIMIZE_PANEL');
|
||||
export const updateIsFullScreenMode = createAction('UPDATE_IS_FULL_SCREEN_MODE');
|
||||
export const updateUseMargins = createAction('UPDATE_USE_MARGINS');
|
||||
export const updateHidePanelTitles = createAction('HIDE_PANEL_TITLES');
|
||||
export const updateTimeRange = createAction('UPDATE_TIME_RANGE');
|
||||
export const updateFilters = createAction('UPDATE_FILTERS');
|
||||
export const updateQuery = createAction('UPDATE_QUERY');
|
115
src/core_plugins/kibana/public/dashboard/actions/view.ts
Normal file
115
src/core_plugins/kibana/public/dashboard/actions/view.ts
Normal file
|
@ -0,0 +1,115 @@
|
|||
/*
|
||||
* 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 { createAction } from 'redux-actions';
|
||||
import { Filters, Query, TimeRange } from 'ui/embeddable';
|
||||
import { KibanaAction } from '../../selectors/types';
|
||||
import { DashboardViewMode } from '../dashboard_view_mode';
|
||||
import { PanelId } from '../selectors';
|
||||
|
||||
export enum ViewActionTypeKeys {
|
||||
UPDATE_VIEW_MODE = 'UPDATE_VIEW_MODE',
|
||||
SET_VISIBLE_CONTEXT_MENU_PANEL_ID = 'SET_VISIBLE_CONTEXT_MENU_PANEL_ID',
|
||||
MAXIMIZE_PANEl = 'MAXIMIZE_PANEl',
|
||||
MINIMIZE_PANEL = 'MINIMIZE_PANEL',
|
||||
UPDATE_IS_FULL_SCREEN_MODE = 'UPDATE_IS_FULL_SCREEN_MODE',
|
||||
UPDATE_USE_MARGINS = 'UPDATE_USE_MARGINS',
|
||||
UPDATE_HIDE_PANEL_TITLES = 'UPDATE_HIDE_PANEL_TITLES',
|
||||
UPDATE_TIME_RANGE = 'UPDATE_TIME_RANGE',
|
||||
UPDATE_FILTERS = 'UPDATE_FILTERS',
|
||||
UPDATE_QUERY = 'UPDATE_QUERY',
|
||||
}
|
||||
|
||||
export interface UpdateViewModeAction
|
||||
extends KibanaAction<
|
||||
ViewActionTypeKeys.UPDATE_VIEW_MODE,
|
||||
DashboardViewMode
|
||||
> {}
|
||||
|
||||
export interface SetVisibleContextMenuPanelIdAction
|
||||
extends KibanaAction<
|
||||
ViewActionTypeKeys.SET_VISIBLE_CONTEXT_MENU_PANEL_ID,
|
||||
PanelId
|
||||
> {}
|
||||
|
||||
export interface MaximizePanelAction
|
||||
extends KibanaAction<ViewActionTypeKeys.MAXIMIZE_PANEl, PanelId> {}
|
||||
|
||||
export interface MinimizePanelAction
|
||||
extends KibanaAction<ViewActionTypeKeys.MINIMIZE_PANEL, undefined> {}
|
||||
|
||||
export interface UpdateIsFullScreenModeAction
|
||||
extends KibanaAction<
|
||||
ViewActionTypeKeys.UPDATE_IS_FULL_SCREEN_MODE,
|
||||
boolean
|
||||
> {}
|
||||
|
||||
export interface UpdateUseMarginsAction
|
||||
extends KibanaAction<ViewActionTypeKeys.UPDATE_USE_MARGINS, boolean> {}
|
||||
|
||||
export interface UpdateHidePanelTitlesAction
|
||||
extends KibanaAction<ViewActionTypeKeys.UPDATE_HIDE_PANEL_TITLES, boolean> {}
|
||||
|
||||
export interface UpdateTimeRangeAction
|
||||
extends KibanaAction<ViewActionTypeKeys.UPDATE_TIME_RANGE, TimeRange> {}
|
||||
|
||||
export interface UpdateFiltersAction
|
||||
extends KibanaAction<ViewActionTypeKeys.UPDATE_FILTERS, Filters> {}
|
||||
|
||||
export interface UpdateQueryAction
|
||||
extends KibanaAction<ViewActionTypeKeys.UPDATE_QUERY, Query> {}
|
||||
|
||||
export type ViewActions =
|
||||
| UpdateViewModeAction
|
||||
| SetVisibleContextMenuPanelIdAction
|
||||
| MaximizePanelAction
|
||||
| MinimizePanelAction
|
||||
| UpdateIsFullScreenModeAction
|
||||
| UpdateUseMarginsAction
|
||||
| UpdateHidePanelTitlesAction
|
||||
| UpdateTimeRangeAction
|
||||
| UpdateFiltersAction
|
||||
| UpdateQueryAction;
|
||||
|
||||
export const updateViewMode = createAction<string>(
|
||||
ViewActionTypeKeys.UPDATE_VIEW_MODE
|
||||
);
|
||||
export const setVisibleContextMenuPanelId = createAction<PanelId>(
|
||||
ViewActionTypeKeys.SET_VISIBLE_CONTEXT_MENU_PANEL_ID
|
||||
);
|
||||
export const maximizePanel = createAction<PanelId>(
|
||||
ViewActionTypeKeys.MAXIMIZE_PANEl
|
||||
);
|
||||
export const minimizePanel = createAction(ViewActionTypeKeys.MINIMIZE_PANEL);
|
||||
export const updateIsFullScreenMode = createAction<boolean>(
|
||||
ViewActionTypeKeys.UPDATE_IS_FULL_SCREEN_MODE
|
||||
);
|
||||
export const updateUseMargins = createAction<boolean>(
|
||||
ViewActionTypeKeys.UPDATE_USE_MARGINS
|
||||
);
|
||||
export const updateHidePanelTitles = createAction<boolean>(
|
||||
ViewActionTypeKeys.UPDATE_HIDE_PANEL_TITLES
|
||||
);
|
||||
export const updateTimeRange = createAction<TimeRange>(
|
||||
ViewActionTypeKeys.UPDATE_TIME_RANGE
|
||||
);
|
||||
export const updateFilters = createAction<Filters>(
|
||||
ViewActionTypeKeys.UPDATE_FILTERS
|
||||
);
|
||||
export const updateQuery = createAction<Query>(ViewActionTypeKeys.UPDATE_QUERY);
|
|
@ -70,4 +70,4 @@
|
|||
>
|
||||
</dashboard-viewport-provider>
|
||||
|
||||
</dashboard-app>
|
||||
</dashboard-app>
|
|
@ -29,30 +29,30 @@ export function dashboardContextProvider(Private, getAppState) {
|
|||
const appState = getAppState();
|
||||
const queryFilter = Private(FilterBarQueryFilterProvider);
|
||||
const bool = { must: [], must_not: [] };
|
||||
if (!appState) return { bool: bool };
|
||||
if (!appState) { return { bool: bool }; }
|
||||
const filterBarFilters = queryFilter.getFilters();
|
||||
const queryBarQuery = appState.query;
|
||||
|
||||
if (queryBarQuery.language === 'lucene') {
|
||||
// Add the query bar filter, its handled differently.
|
||||
const query = luceneStringToDsl(queryBarQuery.query);
|
||||
if (query) bool.must.push(query);
|
||||
if (query) { bool.must.push(query); }
|
||||
}
|
||||
|
||||
// Add each of the filter bar filters
|
||||
_.each(filterBarFilters, function (filter) {
|
||||
const esFilter = _.omit(filter, function (val, key) {
|
||||
if (key === 'meta' || key[0] === '$') return true;
|
||||
if (key === 'meta' || key[0] === '$') { return true; }
|
||||
return false;
|
||||
});
|
||||
|
||||
if (filter.meta.disabled) return;
|
||||
if (filter.meta.disabled) { return; }
|
||||
if (filter.meta.negate) {
|
||||
bool.must_not = bool.must_not || [];
|
||||
if (esFilter.query || esFilter) bool.must_not.push(migrateFilter(esFilter.query || esFilter));
|
||||
if (esFilter.query || esFilter) { bool.must_not.push(migrateFilter(esFilter.query || esFilter)); }
|
||||
} else {
|
||||
bool.must = bool.must || [];
|
||||
if (esFilter.query || esFilter) bool.must.push(migrateFilter(esFilter.query || esFilter));
|
||||
if (esFilter.query || esFilter) { bool.must.push(migrateFilter(esFilter.query || esFilter)); }
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
@ -17,16 +17,7 @@
|
|||
* under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* A dashboard mode.
|
||||
* @typedef {string} DashboardMode
|
||||
*/
|
||||
|
||||
/**
|
||||
* Dashboard view modes.
|
||||
* @type {{EDIT: DashboardViewMode, VIEW: DashboardViewMode}}
|
||||
*/
|
||||
export const DashboardViewMode = {
|
||||
EDIT: 'edit',
|
||||
VIEW: 'view'
|
||||
};
|
||||
export enum DashboardViewMode {
|
||||
EDIT = 'edit',
|
||||
VIEW = 'view',
|
||||
}
|
|
@ -62,12 +62,12 @@ test('Panel header shows embeddable title when nothing is set on the panel', ()
|
|||
});
|
||||
|
||||
test('Panel header shows panel title when it is set on the panel', () => {
|
||||
store.dispatch(setPanelTitle('my custom panel title', 'foo1'));
|
||||
store.dispatch(setPanelTitle({ title: 'my custom panel title', panelId: 'foo1' }));
|
||||
expect(findTestSubject(component, 'dashboardPanelTitle').text()).toBe('my custom panel title');
|
||||
});
|
||||
|
||||
test('Panel header shows no panel title when it is set to an empty string on the panel', () => {
|
||||
store.dispatch(setPanelTitle('', 'foo1'));
|
||||
store.dispatch(setPanelTitle({ title: '', panelId: 'foo1' }));
|
||||
expect(findTestSubject(component, 'dashboardPanelTitle').text()).toBe('');
|
||||
});
|
||||
|
||||
|
|
|
@ -83,7 +83,7 @@ const mapDispatchToProps = (dispatch, { panelId }) => ({
|
|||
onMaximizePanel: () => dispatch(maximizePanel(panelId)),
|
||||
onMinimizePanel: () => dispatch(minimizePanel()),
|
||||
onResetPanelTitle: () => dispatch(resetPanelTitle(panelId)),
|
||||
onUpdatePanelTitle: (newTitle) => dispatch(setPanelTitle(newTitle, panelId)),
|
||||
onUpdatePanelTitle: (newTitle) => dispatch(setPanelTitle({ title: newTitle, panelId: panelId })),
|
||||
});
|
||||
|
||||
const mergeProps = (stateProps, dispatchProps, ownProps) => {
|
||||
|
|
|
@ -1,121 +0,0 @@
|
|||
/*
|
||||
* 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 { handleActions } from 'redux-actions';
|
||||
import _ from 'lodash';
|
||||
|
||||
import {
|
||||
embeddableIsInitializing,
|
||||
embeddableError,
|
||||
embeddableIsInitialized,
|
||||
setStagedFilter,
|
||||
clearStagedFilters,
|
||||
deletePanel,
|
||||
} from '../actions';
|
||||
|
||||
export const embeddables = handleActions({
|
||||
[clearStagedFilters]:
|
||||
(embeddables) => {
|
||||
return _.mapValues(embeddables, (embeddable) => _.omit({ ...embeddable }, ['stagedFilter']));
|
||||
},
|
||||
|
||||
[embeddableIsInitialized]:
|
||||
/**
|
||||
*
|
||||
* @param embeddables {Object.<string, EmbeddableState>}
|
||||
* @param payload {Object}
|
||||
* @param payload.panelId {string} Panel id of embeddable that was initialized
|
||||
* @param payload.metadata {object} Metadata for the embeddable that was initialized
|
||||
* @return {Object.<string, EmbeddableState>}
|
||||
*/
|
||||
(embeddables, { payload }) => {
|
||||
return {
|
||||
...embeddables,
|
||||
[payload.panelId]: {
|
||||
...embeddables[payload.panelId],
|
||||
initialized: true,
|
||||
metadata: { ...payload.metadata },
|
||||
}
|
||||
};
|
||||
},
|
||||
|
||||
// TODO: Currently only saved search uses this to apply a filter. When visualize uses it too, we will need to
|
||||
// support multiple staged filters.
|
||||
[setStagedFilter]:
|
||||
(embeddables, { payload }) => {
|
||||
return {
|
||||
...embeddables,
|
||||
[payload.panelId]: {
|
||||
...embeddables[payload.panelId],
|
||||
stagedFilter: payload.stagedFilter,
|
||||
}
|
||||
};
|
||||
},
|
||||
|
||||
[deletePanel]:
|
||||
/**
|
||||
*
|
||||
* @param embeddables {Object.<string, EmbeddableState>}
|
||||
* @param payload {String} The id of the panel to delete
|
||||
* @return {Object.<string, EmbeddableState>}
|
||||
*/
|
||||
(embeddables, { payload }) => {
|
||||
const embeddablesCopy = { ...embeddables };
|
||||
delete embeddablesCopy[payload];
|
||||
return embeddablesCopy;
|
||||
},
|
||||
|
||||
[embeddableIsInitializing]:
|
||||
/**
|
||||
*
|
||||
* @param embeddables {Object.<string, EmbeddableState>}
|
||||
* @param payload {Object}
|
||||
* @param payload.panelId {String}
|
||||
* @param payload.embeddable {Embeddable}
|
||||
* @return {Object.<string, EmbeddableState>}
|
||||
*/
|
||||
(embeddables, { payload }) => {
|
||||
return {
|
||||
...embeddables,
|
||||
[payload]: {
|
||||
initialized: false,
|
||||
error: undefined,
|
||||
}
|
||||
};
|
||||
},
|
||||
|
||||
[embeddableError]:
|
||||
/**
|
||||
*
|
||||
* @param embeddables {Object.<string, EmbeddableState>}
|
||||
* @param payload {Object}
|
||||
* @param payload.panelId {String}
|
||||
* @param payload.error {String|Object}
|
||||
* @return {Object.<string, EmbeddableState>}
|
||||
*/
|
||||
(embeddables, { payload }) => {
|
||||
return {
|
||||
...embeddables,
|
||||
[payload.panelId]: {
|
||||
...embeddables[payload.panelId],
|
||||
error: payload.error,
|
||||
}
|
||||
};
|
||||
}
|
||||
}, {});
|
|
@ -17,17 +17,26 @@
|
|||
* under the License.
|
||||
*/
|
||||
|
||||
import { getEmbeddableError, getEmbeddableInitialized } from '../../selectors';
|
||||
import { store } from '../../store';
|
||||
import {
|
||||
embeddableIsInitializing, setPanels,
|
||||
} from '../actions';
|
||||
import {
|
||||
getEmbeddableError,
|
||||
getEmbeddableInitialized,
|
||||
} from '../../selectors';
|
||||
import { embeddableIsInitializing, setPanels } from '../actions';
|
||||
|
||||
beforeAll(() => {
|
||||
store.dispatch(setPanels({ 'foo1': { panelIndex: 'foo1' } }));
|
||||
const panelData = {
|
||||
embeddableConfig: {},
|
||||
gridData: {
|
||||
h: 0,
|
||||
id: '0',
|
||||
w: 0,
|
||||
x: 0,
|
||||
y: 0,
|
||||
},
|
||||
id: '123',
|
||||
panelIndex: 'foo1',
|
||||
type: 'mySpecialType',
|
||||
version: '123',
|
||||
};
|
||||
store.dispatch(setPanels({ foo1: panelData }));
|
||||
});
|
||||
|
||||
describe('embeddableIsInitializing', () => {
|
||||
|
@ -42,4 +51,3 @@ describe('embeddableIsInitializing', () => {
|
|||
expect(error).toBe(undefined);
|
||||
});
|
||||
});
|
||||
|
121
src/core_plugins/kibana/public/dashboard/reducers/embeddables.ts
Normal file
121
src/core_plugins/kibana/public/dashboard/reducers/embeddables.ts
Normal file
|
@ -0,0 +1,121 @@
|
|||
/*
|
||||
* 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 _ from 'lodash';
|
||||
import { Reducer } from 'redux';
|
||||
|
||||
import {
|
||||
EmbeddableActionTypeKeys,
|
||||
EmbeddableErrorActionPayload,
|
||||
EmbeddableIsInitializedActionPayload,
|
||||
PanelActionTypeKeys,
|
||||
SetStagedFilterActionPayload,
|
||||
} from '../actions';
|
||||
import {
|
||||
EmbeddableReduxState,
|
||||
EmbeddablesMap,
|
||||
PanelId,
|
||||
} from '../selectors/types';
|
||||
|
||||
const embeddableIsInitializing = (
|
||||
embeddables: EmbeddablesMap,
|
||||
panelId: PanelId
|
||||
): EmbeddablesMap => ({
|
||||
...embeddables,
|
||||
[panelId]: {
|
||||
error: undefined,
|
||||
initialized: false,
|
||||
metadata: {},
|
||||
stagedFilter: undefined,
|
||||
},
|
||||
});
|
||||
|
||||
const embeddableIsInitialized = (
|
||||
embeddables: EmbeddablesMap,
|
||||
{ panelId, metadata }: EmbeddableIsInitializedActionPayload
|
||||
): EmbeddablesMap => ({
|
||||
...embeddables,
|
||||
[panelId]: {
|
||||
...embeddables[panelId],
|
||||
initialized: true,
|
||||
metadata: { ...metadata },
|
||||
},
|
||||
});
|
||||
|
||||
const setStagedFilter = (
|
||||
embeddables: EmbeddablesMap,
|
||||
{ panelId, stagedFilter }: SetStagedFilterActionPayload
|
||||
): EmbeddablesMap => ({
|
||||
...embeddables,
|
||||
[panelId]: {
|
||||
...embeddables[panelId],
|
||||
stagedFilter,
|
||||
},
|
||||
});
|
||||
|
||||
const embeddableError = (
|
||||
embeddables: EmbeddablesMap,
|
||||
payload: EmbeddableErrorActionPayload
|
||||
): EmbeddablesMap => ({
|
||||
...embeddables,
|
||||
[payload.panelId]: {
|
||||
...embeddables[payload.panelId],
|
||||
error: payload.error,
|
||||
},
|
||||
});
|
||||
|
||||
const clearStagedFilters = (embeddables: EmbeddablesMap): EmbeddablesMap => {
|
||||
const omitStagedFilters = (
|
||||
embeddable: EmbeddableReduxState
|
||||
): EmbeddablesMap => _.omit({ ...embeddable }, ['stagedFilter']);
|
||||
return _.mapValues<EmbeddablesMap>(embeddables, omitStagedFilters);
|
||||
};
|
||||
|
||||
const deleteEmbeddable = (
|
||||
embeddables: EmbeddablesMap,
|
||||
panelId: PanelId
|
||||
): EmbeddablesMap => {
|
||||
const embeddablesCopy = { ...embeddables };
|
||||
delete embeddablesCopy[panelId];
|
||||
return embeddablesCopy;
|
||||
};
|
||||
|
||||
export const embeddablesReducer: Reducer<EmbeddablesMap> = (
|
||||
embeddables = {},
|
||||
action
|
||||
): EmbeddablesMap => {
|
||||
switch (
|
||||
action.type as EmbeddableActionTypeKeys | PanelActionTypeKeys.DELETE_PANEL
|
||||
) {
|
||||
case EmbeddableActionTypeKeys.EMBEDDABLE_IS_INITIALIZING:
|
||||
return embeddableIsInitializing(embeddables, action.payload);
|
||||
case EmbeddableActionTypeKeys.EMBEDDABLE_IS_INITIALIZED:
|
||||
return embeddableIsInitialized(embeddables, action.payload);
|
||||
case EmbeddableActionTypeKeys.SET_STAGED_FILTER:
|
||||
return setStagedFilter(embeddables, action.payload);
|
||||
case EmbeddableActionTypeKeys.CLEAR_STAGED_FILTERS:
|
||||
return clearStagedFilters(embeddables);
|
||||
case EmbeddableActionTypeKeys.EMBEDDABLE_ERROR:
|
||||
return embeddableError(embeddables, action.payload);
|
||||
case PanelActionTypeKeys.DELETE_PANEL:
|
||||
return deleteEmbeddable(embeddables, action.payload);
|
||||
default:
|
||||
return embeddables;
|
||||
}
|
||||
};
|
|
@ -18,25 +18,17 @@
|
|||
*/
|
||||
|
||||
import { combineReducers } from 'redux';
|
||||
import {
|
||||
embeddables,
|
||||
} from './embeddables';
|
||||
import { embeddablesReducer } from './embeddables';
|
||||
|
||||
import {
|
||||
panels,
|
||||
} from './panels';
|
||||
import { panelsReducer } from './panels';
|
||||
|
||||
import {
|
||||
view,
|
||||
} from './view';
|
||||
import { viewReducer } from './view';
|
||||
|
||||
import {
|
||||
metadata,
|
||||
} from './metadata';
|
||||
import { metadataReducer } from './metadata';
|
||||
|
||||
export const dashboard = combineReducers({
|
||||
view,
|
||||
panels,
|
||||
embeddables,
|
||||
metadata,
|
||||
embeddables: embeddablesReducer,
|
||||
metadata: metadataReducer,
|
||||
panels: panelsReducer,
|
||||
view: viewReducer,
|
||||
});
|
|
@ -1,37 +0,0 @@
|
|||
/*
|
||||
* 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 { handleActions } from 'redux-actions';
|
||||
import { updateTitle, updateDescription } from '../actions';
|
||||
|
||||
export const metadata = handleActions({
|
||||
[updateTitle]: (state, { payload }) => ({
|
||||
...state,
|
||||
title: payload
|
||||
}),
|
||||
|
||||
[updateDescription]: (state, { payload }) => ({
|
||||
...state,
|
||||
description: payload
|
||||
}),
|
||||
|
||||
}, {
|
||||
title: '',
|
||||
description: '',
|
||||
});
|
|
@ -0,0 +1,60 @@
|
|||
/*
|
||||
* 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 { Reducer } from 'redux';
|
||||
import {
|
||||
MetadataActions,
|
||||
MetadataActionTypeKeys,
|
||||
UpdateDescriptionActionPayload,
|
||||
UpdateTitleActionPayload,
|
||||
} from '../actions';
|
||||
import { DashboardMetadata } from '../selectors';
|
||||
|
||||
const updateTitle = (
|
||||
metadata: DashboardMetadata,
|
||||
title: UpdateTitleActionPayload
|
||||
) => ({
|
||||
...metadata,
|
||||
title,
|
||||
});
|
||||
|
||||
const updateDescription = (
|
||||
metadata: DashboardMetadata,
|
||||
description: UpdateDescriptionActionPayload
|
||||
) => ({
|
||||
...metadata,
|
||||
description,
|
||||
});
|
||||
|
||||
export const metadataReducer: Reducer<DashboardMetadata> = (
|
||||
metadata = {
|
||||
description: '',
|
||||
title: '',
|
||||
},
|
||||
action
|
||||
): DashboardMetadata => {
|
||||
switch ((action as MetadataActions).type) {
|
||||
case MetadataActionTypeKeys.UPDATE_TITLE:
|
||||
return updateTitle(metadata, action.payload);
|
||||
case MetadataActionTypeKeys.UPDATE_DESCRIPTION:
|
||||
return updateDescription(metadata, action.payload);
|
||||
default:
|
||||
return metadata;
|
||||
}
|
||||
};
|
|
@ -1,120 +0,0 @@
|
|||
/*
|
||||
* 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 _ from 'lodash';
|
||||
import { handleActions } from 'redux-actions';
|
||||
|
||||
import {
|
||||
deletePanel,
|
||||
updatePanel,
|
||||
updatePanels,
|
||||
setPanels,
|
||||
resetPanelTitle,
|
||||
setPanelTitle,
|
||||
} from '../actions';
|
||||
|
||||
/**
|
||||
*
|
||||
* @param panel {PanelState} - new panel data (can be partial data) to merge with possibly existing panel data in
|
||||
* the panels mapping.
|
||||
* @param panel.panelIndex {String} The new panel data must specify the panelIndex so we know which panel to merge with.
|
||||
* @param panels {Object.<string, PanelState>}
|
||||
* @return {PanelState} - a new PanelState which has the merged data.
|
||||
*/
|
||||
function mergePanelData(panel, panels) {
|
||||
return _.defaultsDeep(panel, panels[panel.panelIndex]);
|
||||
}
|
||||
|
||||
export const panels = handleActions({
|
||||
[setPanels]:
|
||||
/**
|
||||
*
|
||||
* @param panels {Object.<string, PanelState>}
|
||||
* @param payload {Object.<string, PanelState>}
|
||||
* @return {Object.<string, PanelState>}
|
||||
*/
|
||||
(panels, { payload }) => _.cloneDeep(payload),
|
||||
|
||||
[updatePanels]:
|
||||
/**
|
||||
*
|
||||
* @param panels {Object.<string, PanelState>}
|
||||
* @param payload {Object.<string, PanelState>}
|
||||
* @return {Object.<string, PanelState>}
|
||||
*/
|
||||
(panels, { payload }) => {
|
||||
const panelsCopy = { ...panels };
|
||||
Object.values(payload).forEach(panel => {
|
||||
panelsCopy[panel.panelIndex] = mergePanelData(panel, panels);
|
||||
});
|
||||
return panelsCopy;
|
||||
},
|
||||
|
||||
[deletePanel]:
|
||||
/**
|
||||
*
|
||||
* @param panels {Object.<string, PanelState>}
|
||||
* @param payload {string} The panelIndex of the panel to delete
|
||||
* @return {Object.<string, PanelState>}
|
||||
*/
|
||||
(panels, { payload }) => {
|
||||
const panelsCopy = { ...panels };
|
||||
delete panelsCopy[payload];
|
||||
return panelsCopy;
|
||||
},
|
||||
|
||||
[updatePanel]:
|
||||
/**
|
||||
* @param panels {Object.<string, PanelState>}
|
||||
* @param payload {PanelState} The new panel state (is merged with existing).
|
||||
* @param payload.panelIndex {string} The id of the panel to update.
|
||||
* @return {Object.<string, PanelState>}
|
||||
*/
|
||||
(panels, { payload }) => ({
|
||||
...panels,
|
||||
[payload.panelIndex]: mergePanelData(payload, panels),
|
||||
}),
|
||||
|
||||
[resetPanelTitle]:
|
||||
/**
|
||||
* @param panels {Object.<string, PanelState>}
|
||||
* @param payload {String} The id of the panel to reset it's title.
|
||||
* @return {Object.<string, PanelState>}
|
||||
*/
|
||||
(panels, { payload }) => ({
|
||||
...panels,
|
||||
[payload]: {
|
||||
...panels[payload],
|
||||
title: undefined,
|
||||
}
|
||||
}),
|
||||
|
||||
[setPanelTitle]:
|
||||
/**
|
||||
* @param panels {Object.<string, PanelState>}
|
||||
* @param payload {PanelState} The new panel state (is merged with existing).
|
||||
* @param payload.panelIndex {String} The id of the panel to reset it's title.
|
||||
* @param payload.title {String} The new title to use.
|
||||
* @return {Object.<string, PanelState>}
|
||||
*/
|
||||
(panels, { payload }) => ({
|
||||
...panels,
|
||||
[payload.panelIndex]: mergePanelData(payload, panels),
|
||||
}),
|
||||
}, {});
|
|
@ -17,27 +17,37 @@
|
|||
* under the License.
|
||||
*/
|
||||
|
||||
import { getPanel, getPanelType } from '../../selectors';
|
||||
import { store } from '../../store';
|
||||
import { updatePanel, updatePanels } from '../actions';
|
||||
import {
|
||||
getPanel,
|
||||
getPanelType,
|
||||
} from '../../selectors';
|
||||
|
||||
test('UpdatePanel updates a panel', () => {
|
||||
store.dispatch(updatePanels([{ panelIndex: '1', gridData: {} }]));
|
||||
|
||||
store.dispatch(updatePanel({
|
||||
const panelData = {
|
||||
embeddableConfig: {},
|
||||
gridData: {
|
||||
h: 0,
|
||||
id: '0',
|
||||
w: 0,
|
||||
x: 0,
|
||||
y: 0,
|
||||
},
|
||||
id: '123',
|
||||
panelIndex: '1',
|
||||
type: 'mySpecialType',
|
||||
version: '123',
|
||||
};
|
||||
store.dispatch(updatePanels({ '1': panelData }));
|
||||
const newPanelData = {
|
||||
...panelData,
|
||||
gridData: {
|
||||
h: 1,
|
||||
id: '1',
|
||||
w: 10,
|
||||
x: 1,
|
||||
y: 5,
|
||||
w: 10,
|
||||
h: 1,
|
||||
id: '1'
|
||||
}
|
||||
}));
|
||||
},
|
||||
};
|
||||
store.dispatch(updatePanel(newPanelData));
|
||||
|
||||
const panel = getPanel(store.getState(), '1');
|
||||
expect(panel.gridData.x).toBe(1);
|
103
src/core_plugins/kibana/public/dashboard/reducers/panels.ts
Normal file
103
src/core_plugins/kibana/public/dashboard/reducers/panels.ts
Normal file
|
@ -0,0 +1,103 @@
|
|||
/*
|
||||
* 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 _ from 'lodash';
|
||||
import { Reducer } from 'redux';
|
||||
import {
|
||||
PanelActions,
|
||||
PanelActionTypeKeys,
|
||||
SetPanelTitleActionPayload,
|
||||
} from '../actions';
|
||||
import { PanelId, PanelsMap, PanelState } from '../selectors';
|
||||
|
||||
/**
|
||||
* @param panel - New panel data (can be partial data) to merge with possibly existing panel data in
|
||||
* the panels mapping.
|
||||
* @param panels
|
||||
* @return a new PanelState which has the merged data.
|
||||
*/
|
||||
function mergePanelData(panel: PanelState, panels: PanelsMap): PanelState {
|
||||
return _.defaultsDeep(panel, panels[panel.panelIndex]);
|
||||
}
|
||||
|
||||
const deletePanel = (panels: PanelsMap, panelId: PanelId): PanelsMap => {
|
||||
const panelsCopy = { ...panels };
|
||||
delete panelsCopy[panelId];
|
||||
return panelsCopy;
|
||||
};
|
||||
|
||||
const updatePanel = (panels: PanelsMap, panelState: PanelState): PanelsMap => ({
|
||||
...panels,
|
||||
[panelState.panelIndex]: mergePanelData(panelState, panels),
|
||||
});
|
||||
|
||||
const updatePanels = (
|
||||
panels: PanelsMap,
|
||||
updatedPanels: PanelsMap
|
||||
): PanelsMap => {
|
||||
const panelsCopy = { ...panels };
|
||||
Object.values(updatedPanels).forEach(panel => {
|
||||
panelsCopy[panel.panelIndex] = mergePanelData(panel, panels);
|
||||
});
|
||||
return panelsCopy;
|
||||
};
|
||||
|
||||
const resetPanelTitle = (panels: PanelsMap, panelId: PanelId) => ({
|
||||
...panels,
|
||||
[panelId]: {
|
||||
...panels[panelId],
|
||||
title: undefined,
|
||||
},
|
||||
});
|
||||
|
||||
const setPanelTitle = (
|
||||
panels: PanelsMap,
|
||||
payload: SetPanelTitleActionPayload
|
||||
) => ({
|
||||
...panels,
|
||||
[payload.panelId]: {
|
||||
...panels[payload.panelId],
|
||||
title: payload.title,
|
||||
},
|
||||
});
|
||||
|
||||
const setPanels = (panels: PanelsMap, newPanels: PanelsMap) =>
|
||||
_.cloneDeep(newPanels);
|
||||
|
||||
export const panelsReducer: Reducer<PanelsMap> = (
|
||||
panels = {},
|
||||
action
|
||||
): PanelsMap => {
|
||||
switch ((action as PanelActions).type) {
|
||||
case PanelActionTypeKeys.DELETE_PANEL:
|
||||
return deletePanel(panels, action.payload);
|
||||
case PanelActionTypeKeys.UPDATE_PANEL:
|
||||
return updatePanel(panels, action.payload);
|
||||
case PanelActionTypeKeys.UPDATE_PANELS:
|
||||
return updatePanels(panels, action.payload);
|
||||
case PanelActionTypeKeys.RESET_PANEl_TITLE:
|
||||
return resetPanelTitle(panels, action.payload);
|
||||
case PanelActionTypeKeys.SET_PANEl_TITLE:
|
||||
return setPanelTitle(panels, action.payload);
|
||||
case PanelActionTypeKeys.SET_PANELS:
|
||||
return setPanels(panels, action.payload);
|
||||
default:
|
||||
return panels;
|
||||
}
|
||||
};
|
|
@ -1,87 +0,0 @@
|
|||
/*
|
||||
* 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 { handleActions, combineActions } from 'redux-actions';
|
||||
import {
|
||||
updateViewMode,
|
||||
maximizePanel,
|
||||
minimizePanel,
|
||||
updateUseMargins,
|
||||
updateHidePanelTitles,
|
||||
updateIsFullScreenMode,
|
||||
updateTimeRange,
|
||||
updateFilters,
|
||||
updateQuery,
|
||||
setVisibleContextMenuPanelId,
|
||||
} from '../actions';
|
||||
|
||||
import { DashboardViewMode } from '../dashboard_view_mode';
|
||||
|
||||
export const view = handleActions({
|
||||
[setVisibleContextMenuPanelId]: (state, { payload }) => ({
|
||||
...state,
|
||||
visibleContextMenuPanelId: payload
|
||||
}),
|
||||
|
||||
[updateViewMode]: (state, { payload }) => ({
|
||||
...state,
|
||||
viewMode: payload
|
||||
}),
|
||||
|
||||
[updateTimeRange]: (state, { payload }) => ({
|
||||
...state,
|
||||
timeRange: payload
|
||||
}),
|
||||
|
||||
[updateFilters]: (state, { payload }) => ({
|
||||
...state,
|
||||
filters: payload
|
||||
}),
|
||||
|
||||
[updateQuery]: (state, { payload }) => ({
|
||||
...state,
|
||||
query: payload
|
||||
}),
|
||||
|
||||
[updateUseMargins]: (state, { payload }) => ({
|
||||
...state,
|
||||
useMargins: payload
|
||||
}),
|
||||
|
||||
[updateHidePanelTitles]: (state, { payload }) => ({
|
||||
...state,
|
||||
hidePanelTitles: payload
|
||||
}),
|
||||
|
||||
[combineActions(maximizePanel, minimizePanel)]: (state, { payload }) => ({
|
||||
...state,
|
||||
maximizedPanelId: payload
|
||||
}),
|
||||
|
||||
[updateIsFullScreenMode]: (state, { payload }) => ({
|
||||
...state,
|
||||
isFullScreenMode: payload
|
||||
}),
|
||||
}, {
|
||||
isFullScreenMode: false,
|
||||
viewMode: DashboardViewMode.VIEW,
|
||||
maximizedPanelId: undefined,
|
||||
useMargins: true,
|
||||
hidePanelTitles: false,
|
||||
});
|
|
@ -19,16 +19,16 @@
|
|||
|
||||
import { store } from '../../store';
|
||||
import {
|
||||
updateIsFullScreenMode,
|
||||
updateViewMode,
|
||||
maximizePanel,
|
||||
minimizePanel,
|
||||
updateIsFullScreenMode,
|
||||
updateViewMode,
|
||||
} from '../actions';
|
||||
|
||||
import {
|
||||
getFullScreenMode,
|
||||
getViewMode,
|
||||
getMaximizedPanelId,
|
||||
getViewMode,
|
||||
} from '../../selectors';
|
||||
|
||||
import { DashboardViewMode } from '../dashboard_view_mode';
|
117
src/core_plugins/kibana/public/dashboard/reducers/view.ts
Normal file
117
src/core_plugins/kibana/public/dashboard/reducers/view.ts
Normal file
|
@ -0,0 +1,117 @@
|
|||
/*
|
||||
* 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 { Reducer } from 'redux';
|
||||
import { ViewActions, ViewActionTypeKeys } from '../actions';
|
||||
|
||||
import { Filters, Query, TimeRange } from 'ui/embeddable';
|
||||
import { QueryLanguageType } from 'ui/embeddable/types';
|
||||
import { DashboardViewMode } from '../dashboard_view_mode';
|
||||
import { PanelId, ViewState } from '../selectors';
|
||||
|
||||
const setVisibleContextMenuPanelId = (view: ViewState, panelId: PanelId) => ({
|
||||
...view,
|
||||
visibleContextMenuPanelId: panelId,
|
||||
});
|
||||
|
||||
const updateHidePanelTitles = (view: ViewState, hidePanelTitles: boolean) => ({
|
||||
...view,
|
||||
hidePanelTitles,
|
||||
});
|
||||
|
||||
const minimizePanel = (view: ViewState) => ({
|
||||
...view,
|
||||
maximizedPanelId: undefined,
|
||||
});
|
||||
|
||||
const maximizePanel = (view: ViewState, panelId: PanelId) => ({
|
||||
...view,
|
||||
maximizedPanelId: panelId,
|
||||
});
|
||||
|
||||
const updateIsFullScreenMode = (
|
||||
view: ViewState,
|
||||
isFullScreenMode: boolean
|
||||
) => ({
|
||||
...view,
|
||||
isFullScreenMode,
|
||||
});
|
||||
|
||||
const updateTimeRange = (view: ViewState, timeRange: TimeRange) => ({
|
||||
...view,
|
||||
timeRange,
|
||||
});
|
||||
|
||||
const updateFilters = (view: ViewState, filters: Filters) => ({
|
||||
...view,
|
||||
filters,
|
||||
});
|
||||
|
||||
const updateQuery = (view: ViewState, query: Query) => ({
|
||||
...view,
|
||||
query,
|
||||
});
|
||||
|
||||
const updateUseMargins = (view: ViewState, useMargins: boolean) => ({
|
||||
...view,
|
||||
useMargins,
|
||||
});
|
||||
|
||||
const updateViewMode = (view: ViewState, viewMode: DashboardViewMode) => ({
|
||||
...view,
|
||||
viewMode,
|
||||
});
|
||||
|
||||
export const viewReducer: Reducer<ViewState> = (
|
||||
view = {
|
||||
filters: [],
|
||||
hidePanelTitles: false,
|
||||
isFullScreenMode: false,
|
||||
query: { language: QueryLanguageType.LUCENE, query: '' },
|
||||
timeRange: { to: 'now', from: 'now-15m' },
|
||||
useMargins: true,
|
||||
viewMode: DashboardViewMode.VIEW,
|
||||
},
|
||||
action
|
||||
): ViewState => {
|
||||
switch ((action as ViewActions).type) {
|
||||
case ViewActionTypeKeys.MINIMIZE_PANEL:
|
||||
return minimizePanel(view);
|
||||
case ViewActionTypeKeys.MAXIMIZE_PANEl:
|
||||
return maximizePanel(view, action.payload);
|
||||
case ViewActionTypeKeys.SET_VISIBLE_CONTEXT_MENU_PANEL_ID:
|
||||
return setVisibleContextMenuPanelId(view, action.payload);
|
||||
case ViewActionTypeKeys.UPDATE_HIDE_PANEL_TITLES:
|
||||
return updateHidePanelTitles(view, action.payload);
|
||||
case ViewActionTypeKeys.UPDATE_TIME_RANGE:
|
||||
return updateTimeRange(view, action.payload);
|
||||
case ViewActionTypeKeys.UPDATE_USE_MARGINS:
|
||||
return updateUseMargins(view, action.payload);
|
||||
case ViewActionTypeKeys.UPDATE_VIEW_MODE:
|
||||
return updateViewMode(view, action.payload);
|
||||
case ViewActionTypeKeys.UPDATE_IS_FULL_SCREEN_MODE:
|
||||
return updateIsFullScreenMode(view, action.payload);
|
||||
case ViewActionTypeKeys.UPDATE_FILTERS:
|
||||
return updateFilters(view, action.payload);
|
||||
case ViewActionTypeKeys.UPDATE_QUERY:
|
||||
return updateQuery(view, action.payload);
|
||||
default:
|
||||
return view;
|
||||
}
|
||||
};
|
171
src/core_plugins/kibana/public/dashboard/selectors/dashboard.ts
Normal file
171
src/core_plugins/kibana/public/dashboard/selectors/dashboard.ts
Normal file
|
@ -0,0 +1,171 @@
|
|||
/*
|
||||
* 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 _ from 'lodash';
|
||||
import {
|
||||
ContainerState,
|
||||
EmbeddableMetadata,
|
||||
Filters,
|
||||
Query,
|
||||
TimeRange,
|
||||
} from 'ui/embeddable';
|
||||
import { DashboardViewMode } from '../dashboard_view_mode';
|
||||
import {
|
||||
DashboardMetadata,
|
||||
DashboardState,
|
||||
EmbeddableReduxState,
|
||||
EmbeddablesMap,
|
||||
PanelId,
|
||||
PanelsMap,
|
||||
PanelState,
|
||||
} from './types';
|
||||
|
||||
export const getPanels = (dashboard: DashboardState): PanelsMap =>
|
||||
dashboard.panels;
|
||||
|
||||
export const getPanel = (
|
||||
dashboard: DashboardState,
|
||||
panelId: PanelId
|
||||
): PanelState => getPanels(dashboard)[panelId];
|
||||
|
||||
export const getPanelType = (
|
||||
dashboard: DashboardState,
|
||||
panelId: PanelId
|
||||
): string => getPanel(dashboard, panelId).type;
|
||||
|
||||
export const getEmbeddables = (dashboard: DashboardState): EmbeddablesMap =>
|
||||
dashboard.embeddables;
|
||||
|
||||
// TODO: rename panel.embeddableConfig to embeddableCustomization. Because it's on the panel that's stored on a
|
||||
// dashboard, renaming this will require a migration step.
|
||||
export const getEmbeddableCustomization = (
|
||||
dashboard: DashboardState,
|
||||
panelId: PanelId
|
||||
): object => getPanel(dashboard, panelId).embeddableConfig;
|
||||
|
||||
export const getEmbeddable = (
|
||||
dashboard: DashboardState,
|
||||
panelId: PanelId
|
||||
): EmbeddableReduxState => dashboard.embeddables[panelId];
|
||||
|
||||
export const getEmbeddableError = (
|
||||
dashboard: DashboardState,
|
||||
panelId: PanelId
|
||||
): string | object | undefined => getEmbeddable(dashboard, panelId).error;
|
||||
|
||||
export const getEmbeddableTitle = (
|
||||
dashboard: DashboardState,
|
||||
panelId: PanelId
|
||||
): string | undefined => {
|
||||
const embeddable = getEmbeddable(dashboard, panelId);
|
||||
return embeddable && embeddable.initialized && embeddable.metadata
|
||||
? embeddable.metadata.title
|
||||
: '';
|
||||
};
|
||||
|
||||
export const getEmbeddableInitialized = (
|
||||
dashboard: DashboardState,
|
||||
panelId: PanelId
|
||||
): boolean => getEmbeddable(dashboard, panelId).initialized;
|
||||
|
||||
export const getEmbeddableStagedFilter = (
|
||||
dashboard: DashboardState,
|
||||
panelId: PanelId
|
||||
): object | undefined => getEmbeddable(dashboard, panelId).stagedFilter;
|
||||
|
||||
export const getEmbeddableMetadata = (
|
||||
dashboard: DashboardState,
|
||||
panelId: PanelId
|
||||
): EmbeddableMetadata | undefined => getEmbeddable(dashboard, panelId).metadata;
|
||||
|
||||
export const getEmbeddableEditUrl = (
|
||||
dashboard: DashboardState,
|
||||
panelId: PanelId
|
||||
): string | undefined => {
|
||||
const embeddable = getEmbeddable(dashboard, panelId);
|
||||
return embeddable && embeddable.initialized && embeddable.metadata
|
||||
? embeddable.metadata.editUrl
|
||||
: '';
|
||||
};
|
||||
|
||||
export const getVisibleContextMenuPanelId = (
|
||||
dashboard: DashboardState
|
||||
): PanelId | undefined => dashboard.view.visibleContextMenuPanelId;
|
||||
|
||||
export const getUseMargins = (dashboard: DashboardState): boolean =>
|
||||
dashboard.view.useMargins;
|
||||
|
||||
export const getViewMode = (dashboard: DashboardState): DashboardViewMode =>
|
||||
dashboard.view.viewMode;
|
||||
|
||||
export const getFullScreenMode = (dashboard: DashboardState): boolean =>
|
||||
dashboard.view.isFullScreenMode;
|
||||
|
||||
export const getHidePanelTitles = (dashboard: DashboardState): boolean =>
|
||||
dashboard.view.hidePanelTitles;
|
||||
|
||||
export const getMaximizedPanelId = (
|
||||
dashboard: DashboardState
|
||||
): PanelId | undefined => dashboard.view.maximizedPanelId;
|
||||
|
||||
export const getTimeRange = (dashboard: DashboardState): TimeRange =>
|
||||
dashboard.view.timeRange;
|
||||
|
||||
export const getFilters = (dashboard: DashboardState): Filters =>
|
||||
dashboard.view.filters;
|
||||
|
||||
export const getQuery = (dashboard: DashboardState): Query =>
|
||||
dashboard.view.query;
|
||||
|
||||
export const getMetadata = (dashboard: DashboardState): DashboardMetadata =>
|
||||
dashboard.metadata;
|
||||
|
||||
export const getTitle = (dashboard: DashboardState): string =>
|
||||
dashboard.metadata.title;
|
||||
|
||||
export const getDescription = (dashboard: DashboardState): string | undefined =>
|
||||
dashboard.metadata.description;
|
||||
|
||||
export const getContainerState = (
|
||||
dashboard: DashboardState,
|
||||
panelId: PanelId
|
||||
): ContainerState => {
|
||||
const time = getTimeRange(dashboard);
|
||||
return {
|
||||
customTitle: getPanel(dashboard, panelId).title,
|
||||
embeddableCustomization: _.cloneDeep(
|
||||
getEmbeddableCustomization(dashboard, panelId) || {}
|
||||
),
|
||||
filters: getFilters(dashboard),
|
||||
hidePanelTitles: getHidePanelTitles(dashboard),
|
||||
isPanelExpanded: getMaximizedPanelId(dashboard) === panelId,
|
||||
query: getQuery(dashboard),
|
||||
timeRange: {
|
||||
from: time.from,
|
||||
to: time.to,
|
||||
},
|
||||
viewMode: getViewMode(dashboard),
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* @return an array of filters any embeddables wish dashboard to apply
|
||||
*/
|
||||
export const getStagedFilters = (dashboard: DashboardState): Filters =>
|
||||
_.compact(_.map(dashboard.embeddables, 'stagedFilter'));
|
|
@ -1,228 +0,0 @@
|
|||
/*
|
||||
* 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 _ from 'lodash';
|
||||
|
||||
/**
|
||||
* @typedef {Object} ViewState
|
||||
* @property {DashboardViewMode} viewMode
|
||||
* @property {boolean} isFullScreenMode
|
||||
* @property {string|undefined} maximizedPanelId
|
||||
* @property {string|undefined} getVisibleContextMenuPanelId
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {Object} EmbeddableReduxState
|
||||
* @property {string} title
|
||||
* @property {string} editUrl
|
||||
* @property {string|object} error
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {Object} DashboardState
|
||||
* @property {Object.<string, PanelState>} panels
|
||||
* @property {Object.<string, EmbeddableReduxState>} embeddables
|
||||
* @property {ViewState} view
|
||||
*/
|
||||
|
||||
/**
|
||||
* @param dashboard {DashboardState}
|
||||
* @return {Object.<string, PanelState>}
|
||||
*/
|
||||
export const getPanels = dashboard => dashboard.panels;
|
||||
|
||||
/**
|
||||
* @param dashboard {DashboardState}
|
||||
* @param panelId {string}
|
||||
* @return {PanelState}
|
||||
*/
|
||||
export const getPanel = (dashboard, panelId) => getPanels(dashboard)[panelId];
|
||||
/**
|
||||
* @param dashboard {DashboardState}
|
||||
* @param panelId {string}
|
||||
* @return {string}
|
||||
*/
|
||||
export const getPanelType = (dashboard, panelId) => getPanel(dashboard, panelId).type;
|
||||
|
||||
export const getEmbeddables = (dashboard) => dashboard.embeddables;
|
||||
|
||||
// TODO: rename panel.embeddableConfig to embeddableCustomization. Because it's on the panel that's stored on a
|
||||
// dashboard, renaming this will require a migration step.
|
||||
export const getEmbeddableCustomization = (dashboard, panelId) => getPanel(dashboard, panelId).embeddableConfig;
|
||||
|
||||
/**
|
||||
* @param dashboard {DashboardState}
|
||||
* @param panelId {string}
|
||||
* @return {EmbeddableReduxState}
|
||||
*/
|
||||
export const getEmbeddable = (dashboard, panelId) => dashboard.embeddables[panelId];
|
||||
|
||||
/**
|
||||
* @param dashboard {DashboardState}
|
||||
* @param panelId {string}
|
||||
* @return {string|Object}
|
||||
*/
|
||||
export const getEmbeddableError = (dashboard, panelId) => getEmbeddable(dashboard, panelId).error;
|
||||
/**
|
||||
* @param dashboard {DashboardState}
|
||||
* @param panelId {string}
|
||||
* @return {string}
|
||||
*/
|
||||
export const getEmbeddableTitle = (dashboard, panelId) => {
|
||||
const embeddable = getEmbeddable(dashboard, panelId);
|
||||
return embeddable && embeddable.initialized ? embeddable.metadata.title : '';
|
||||
};
|
||||
|
||||
/**
|
||||
* @param dashboard {DashboardState}
|
||||
* @param panelId {string}
|
||||
* @return {boolean}
|
||||
*/
|
||||
export const getEmbeddableRenderComplete = (dashboard, panelId) => getEmbeddable(dashboard, panelId).renderComplete;
|
||||
|
||||
/**
|
||||
* @param dashboard {DashboardState}
|
||||
* @param panelId {string}
|
||||
* @return {boolean}
|
||||
*/
|
||||
export const getEmbeddableInitialized = (dashboard, panelId) => getEmbeddable(dashboard, panelId).initialized;
|
||||
|
||||
export const getEmbeddableStagedFilter = (dashboard, panelId) => getEmbeddable(dashboard, panelId).stagedFilter;
|
||||
|
||||
/**
|
||||
*
|
||||
* @param dashboard {DashboardState}
|
||||
* @param panelId {string}
|
||||
* @return {EmbeddableMetadata}
|
||||
*/
|
||||
export const getEmbeddableMetadata = (dashboard, panelId) => getEmbeddable(dashboard, panelId).metadata;
|
||||
|
||||
/**
|
||||
* @param dashboard {DashboardState}
|
||||
* @param panelId {string}
|
||||
* @return {string}
|
||||
*/
|
||||
export const getEmbeddableEditUrl = (dashboard, panelId) => {
|
||||
const embeddable = getEmbeddable(dashboard, panelId);
|
||||
return embeddable && embeddable.initialized ? embeddable.metadata.editUrl : '';
|
||||
};
|
||||
|
||||
|
||||
export const getVisibleContextMenuPanelId = dashboard => dashboard.view.visibleContextMenuPanelId;
|
||||
|
||||
/**
|
||||
* @param dashboard {DashboardState}
|
||||
* @return {boolean}
|
||||
*/
|
||||
export const getUseMargins = dashboard => dashboard.view.useMargins;
|
||||
/**
|
||||
* @param dashboard {DashboardState}
|
||||
* @return {DashboardViewMode}
|
||||
*/
|
||||
export const getViewMode = dashboard => dashboard.view.viewMode;
|
||||
/**
|
||||
* @param dashboard {DashboardState}
|
||||
* @return {boolean}
|
||||
*/
|
||||
export const getFullScreenMode = dashboard => dashboard.view.isFullScreenMode;
|
||||
/**
|
||||
* @param dashboard {DashboardState}
|
||||
* @return {boolean}
|
||||
*/
|
||||
export const getHidePanelTitles = dashboard => dashboard.view.hidePanelTitles;
|
||||
/**
|
||||
* @param dashboard {DashboardState}
|
||||
* @return {string|undefined}
|
||||
*/
|
||||
export const getMaximizedPanelId = dashboard => dashboard.view.maximizedPanelId;
|
||||
|
||||
/**
|
||||
* @param dashboard {DashboardState}
|
||||
* @return {{ from: {string}, to: {string}, mode: {string} }}
|
||||
*/
|
||||
export const getTimeRange = dashboard => dashboard.view.timeRange;
|
||||
|
||||
export const getFilters = dashboard => dashboard.view.filters;
|
||||
|
||||
export const getQuery = dashboard => dashboard.view.query;
|
||||
|
||||
/**
|
||||
* @typedef {Object} DashboardMetadata
|
||||
* @property {string} title
|
||||
* @property {string} description
|
||||
*/
|
||||
|
||||
/**
|
||||
* @param dashboard {DashboardState}
|
||||
* @return {DashboardMetadata}
|
||||
*/
|
||||
export const getMetadata = dashboard => dashboard.metadata;
|
||||
/**
|
||||
* @param dashboard {DashboardState}
|
||||
* @return {string}
|
||||
*/
|
||||
export const getTitle = dashboard => dashboard.metadata.title;
|
||||
/**
|
||||
* @param dashboard {DashboardState}
|
||||
* @return {string}
|
||||
*/
|
||||
export const getDescription = dashboard => dashboard.metadata.description;
|
||||
|
||||
/**
|
||||
* This state object is specifically for communicating to embeddables and it's structure is not tied to
|
||||
* the redux tree structure.
|
||||
* @typedef {Object} ContainerState
|
||||
* @property {DashboardViewMode} viewMode - edit or view mode.
|
||||
* @property {String} timeRange.to - either an absolute time range in utc format or a relative one (e.g. now-15m)
|
||||
* @property {String} timeRange.from - either an absolute time range in utc format or a relative one (e.g. now-15m)
|
||||
* @property {Object} embeddableCustomization
|
||||
* @property {boolean} hidePanelTitles
|
||||
* @property {boolean} isPanelExpanded
|
||||
*/
|
||||
|
||||
/**
|
||||
*
|
||||
* @param dashboard {DashboardState}
|
||||
* @param panelId {string}
|
||||
* @return {ContainerState}
|
||||
*/
|
||||
export const getContainerState = (dashboard, panelId) => {
|
||||
const time = getTimeRange(dashboard);
|
||||
return {
|
||||
timeRange: {
|
||||
to: time.to,
|
||||
from: time.from,
|
||||
},
|
||||
filters: getFilters(dashboard),
|
||||
query: getQuery(dashboard),
|
||||
embeddableCustomization: _.cloneDeep(getEmbeddableCustomization(dashboard, panelId) || {}),
|
||||
hidePanelTitles: getHidePanelTitles(dashboard),
|
||||
customTitle: getPanel(dashboard, panelId).title,
|
||||
viewMode: getViewMode(dashboard),
|
||||
isPanelExpanded: getMaximizedPanelId(dashboard) === panelId,
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
*
|
||||
* @param embeddables {Array.<EmbeddableState>}
|
||||
* @return {Array.<{ field, value, operator, index }>} Array of filters any embeddables wish dashboard to apply
|
||||
*/
|
||||
export const getStagedFilters = ({ embeddables }) => _.compact(_.map(embeddables, 'stagedFilter'));
|
||||
|
|
@ -17,7 +17,6 @@
|
|||
* under the License.
|
||||
*/
|
||||
|
||||
import { createAction } from 'redux-actions';
|
||||
export * from './types';
|
||||
|
||||
export const updateDescription = createAction('UPDATE_DESCRIPTION');
|
||||
export const updateTitle = createAction('UPDATE_TITLE');
|
||||
export * from './dashboard';
|
81
src/core_plugins/kibana/public/dashboard/selectors/types.ts
Normal file
81
src/core_plugins/kibana/public/dashboard/selectors/types.ts
Normal file
|
@ -0,0 +1,81 @@
|
|||
/*
|
||||
* 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 { EmbeddableMetadata, Filters, Query, TimeRange } from 'ui/embeddable';
|
||||
import { DashboardViewMode } from '../dashboard_view_mode';
|
||||
|
||||
export interface ViewState {
|
||||
readonly viewMode: DashboardViewMode;
|
||||
readonly isFullScreenMode: boolean;
|
||||
readonly maximizedPanelId?: string;
|
||||
readonly visibleContextMenuPanelId?: string;
|
||||
readonly timeRange: TimeRange;
|
||||
readonly hidePanelTitles: boolean;
|
||||
readonly useMargins: boolean;
|
||||
readonly query: Query;
|
||||
readonly filters: Filters;
|
||||
}
|
||||
|
||||
export interface GridData {
|
||||
readonly w: number;
|
||||
readonly h: number;
|
||||
readonly x: number;
|
||||
readonly y: number;
|
||||
readonly id: string;
|
||||
}
|
||||
|
||||
export type PanelId = string;
|
||||
export type SavedObjectId = string;
|
||||
|
||||
export interface PanelState {
|
||||
readonly id: SavedObjectId;
|
||||
readonly version: string;
|
||||
readonly type: string;
|
||||
readonly panelIndex: PanelId;
|
||||
readonly embeddableConfig: object;
|
||||
readonly gridData: GridData;
|
||||
readonly title?: string;
|
||||
}
|
||||
|
||||
export interface EmbeddableReduxState {
|
||||
readonly metadata?: EmbeddableMetadata;
|
||||
readonly error?: string | object;
|
||||
readonly initialized: boolean;
|
||||
readonly stagedFilter?: object;
|
||||
}
|
||||
|
||||
export interface PanelsMap {
|
||||
readonly [panelId: string]: PanelState;
|
||||
}
|
||||
|
||||
export interface EmbeddablesMap {
|
||||
readonly [panelId: string]: EmbeddableReduxState;
|
||||
}
|
||||
|
||||
export interface DashboardMetadata {
|
||||
readonly title: string;
|
||||
readonly description?: string;
|
||||
}
|
||||
|
||||
export interface DashboardState {
|
||||
readonly view: ViewState;
|
||||
readonly panels: PanelsMap;
|
||||
readonly embeddables: EmbeddablesMap;
|
||||
readonly metadata: DashboardMetadata;
|
||||
}
|
|
@ -19,11 +19,12 @@
|
|||
|
||||
import { combineReducers } from 'redux';
|
||||
import { dashboard } from './dashboard/reducers';
|
||||
import { CoreKibanaState } from './selectors';
|
||||
|
||||
/**
|
||||
* Only a single reducer now, but eventually there should be one for each sub app that is part of the
|
||||
* core kibana plugins.
|
||||
*/
|
||||
export const reducers = combineReducers({
|
||||
dashboard
|
||||
export const reducers = combineReducers<CoreKibanaState>({
|
||||
dashboard,
|
||||
});
|
|
@ -1,59 +0,0 @@
|
|||
/*
|
||||
* 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 * as DashboardSelectors from '../dashboard/selectors';
|
||||
|
||||
/**
|
||||
* @typedef {Object} KibanaCoreAppState
|
||||
* @property {Object} DashboardState
|
||||
*/
|
||||
|
||||
/**
|
||||
* @param {KibanaCoreAppState} state
|
||||
* @return {DashboardState}
|
||||
*/
|
||||
export const getDashboard = state => state.dashboard;
|
||||
|
||||
export const getPanels = state => DashboardSelectors.getPanels(getDashboard(state));
|
||||
export const getPanel = (state, panelId) => DashboardSelectors.getPanel(getDashboard(state), panelId);
|
||||
export const getPanelType = (state, panelId) => DashboardSelectors.getPanelType(getDashboard(state), panelId);
|
||||
|
||||
export const getEmbeddables = state => DashboardSelectors.getEmbeddables(getDashboard(state));
|
||||
export const getEmbeddableError = (state, panelId) =>
|
||||
DashboardSelectors.getEmbeddableError((getDashboard(state)), panelId);
|
||||
export const getEmbeddableInitialized = (state, panelId) => DashboardSelectors.getEmbeddableInitialized(getDashboard(state), panelId);
|
||||
export const getEmbeddableCustomization =
|
||||
(state, panelId) => DashboardSelectors.getEmbeddableCustomization(getDashboard(state), panelId);
|
||||
export const getEmbeddableStagedFilter =
|
||||
(state, panelId) => DashboardSelectors.getEmbeddableStagedFilter(getDashboard(state), panelId);
|
||||
export const getEmbeddableMetadata =
|
||||
(state, panelId) => DashboardSelectors.getEmbeddableMetadata(getDashboard(state), panelId);
|
||||
|
||||
export const getStagedFilters = state => DashboardSelectors.getStagedFilters(getDashboard(state));
|
||||
export const getViewMode = state => DashboardSelectors.getViewMode(getDashboard(state));
|
||||
export const getFullScreenMode = state => DashboardSelectors.getFullScreenMode(getDashboard(state));
|
||||
export const getMaximizedPanelId = state => DashboardSelectors.getMaximizedPanelId(getDashboard(state));
|
||||
export const getUseMargins = state => DashboardSelectors.getUseMargins(getDashboard(state));
|
||||
export const getHidePanelTitles = state => DashboardSelectors.getHidePanelTitles(getDashboard(state));
|
||||
export const getTimeRange = state => DashboardSelectors.getTimeRange(getDashboard(state));
|
||||
export const getFilters = state => DashboardSelectors.getFilters(getDashboard(state));
|
||||
export const getQuery = state => DashboardSelectors.getQuery(getDashboard(state));
|
||||
|
||||
export const getTitle = state => DashboardSelectors.getTitle(getDashboard(state));
|
||||
export const getDescription = state => DashboardSelectors.getDescription(getDashboard(state));
|
|
@ -0,0 +1,83 @@
|
|||
/*
|
||||
* 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 { Filters, Query, TimeRange } from 'ui/embeddable';
|
||||
import { DashboardViewMode } from '../dashboard/dashboard_view_mode';
|
||||
import * as DashboardSelectors from '../dashboard/selectors';
|
||||
import { PanelId } from '../dashboard/selectors/types';
|
||||
import { CoreKibanaState } from './types';
|
||||
|
||||
export const getDashboard = (
|
||||
state: CoreKibanaState
|
||||
): DashboardSelectors.DashboardState => state.dashboard;
|
||||
|
||||
export const getPanels = (state: CoreKibanaState) =>
|
||||
DashboardSelectors.getPanels(getDashboard(state));
|
||||
export const getPanel = (state: CoreKibanaState, panelId: PanelId) =>
|
||||
DashboardSelectors.getPanel(getDashboard(state), panelId);
|
||||
export const getPanelType = (state: CoreKibanaState, panelId: PanelId) =>
|
||||
DashboardSelectors.getPanelType(getDashboard(state), panelId);
|
||||
|
||||
export const getEmbeddables = (state: CoreKibanaState) =>
|
||||
DashboardSelectors.getEmbeddables(getDashboard(state));
|
||||
export const getEmbeddableError = (state: CoreKibanaState, panelId: PanelId) =>
|
||||
DashboardSelectors.getEmbeddableError(getDashboard(state), panelId);
|
||||
export const getEmbeddableInitialized = (
|
||||
state: CoreKibanaState,
|
||||
panelId: PanelId
|
||||
) => DashboardSelectors.getEmbeddableInitialized(getDashboard(state), panelId);
|
||||
export const getEmbeddableCustomization = (
|
||||
state: CoreKibanaState,
|
||||
panelId: PanelId
|
||||
) =>
|
||||
DashboardSelectors.getEmbeddableCustomization(getDashboard(state), panelId);
|
||||
export const getEmbeddableStagedFilter = (
|
||||
state: CoreKibanaState,
|
||||
panelId: PanelId
|
||||
) => DashboardSelectors.getEmbeddableStagedFilter(getDashboard(state), panelId);
|
||||
export const getEmbeddableMetadata = (
|
||||
state: CoreKibanaState,
|
||||
panelId: PanelId
|
||||
) => DashboardSelectors.getEmbeddableMetadata(getDashboard(state), panelId);
|
||||
|
||||
export const getStagedFilters = (state: CoreKibanaState): Filters =>
|
||||
DashboardSelectors.getStagedFilters(getDashboard(state));
|
||||
export const getViewMode = (state: CoreKibanaState): DashboardViewMode =>
|
||||
DashboardSelectors.getViewMode(getDashboard(state));
|
||||
export const getFullScreenMode = (state: CoreKibanaState): boolean =>
|
||||
DashboardSelectors.getFullScreenMode(getDashboard(state));
|
||||
export const getMaximizedPanelId = (
|
||||
state: CoreKibanaState
|
||||
): PanelId | undefined =>
|
||||
DashboardSelectors.getMaximizedPanelId(getDashboard(state));
|
||||
export const getUseMargins = (state: CoreKibanaState): boolean =>
|
||||
DashboardSelectors.getUseMargins(getDashboard(state));
|
||||
export const getHidePanelTitles = (state: CoreKibanaState): boolean =>
|
||||
DashboardSelectors.getHidePanelTitles(getDashboard(state));
|
||||
export const getTimeRange = (state: CoreKibanaState): TimeRange =>
|
||||
DashboardSelectors.getTimeRange(getDashboard(state));
|
||||
export const getFilters = (state: CoreKibanaState): Filters =>
|
||||
DashboardSelectors.getFilters(getDashboard(state));
|
||||
export const getQuery = (state: CoreKibanaState): Query =>
|
||||
DashboardSelectors.getQuery(getDashboard(state));
|
||||
|
||||
export const getTitle = (state: CoreKibanaState): string =>
|
||||
DashboardSelectors.getTitle(getDashboard(state));
|
||||
export const getDescription = (state: CoreKibanaState): string | undefined =>
|
||||
DashboardSelectors.getDescription(getDashboard(state));
|
|
@ -18,3 +18,4 @@
|
|||
*/
|
||||
|
||||
export * from './dashboard_selectors';
|
||||
export { CoreKibanaState } from './types';
|
30
src/core_plugins/kibana/public/selectors/types.ts
Normal file
30
src/core_plugins/kibana/public/selectors/types.ts
Normal file
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
* 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 { Action } from 'redux';
|
||||
import { DashboardState } from '../dashboard/selectors';
|
||||
|
||||
export interface CoreKibanaState {
|
||||
readonly dashboard: DashboardState;
|
||||
}
|
||||
|
||||
export interface KibanaAction<T, P> extends Action {
|
||||
readonly type: T;
|
||||
readonly payload: P;
|
||||
}
|
|
@ -17,16 +17,35 @@
|
|||
* under the License.
|
||||
*/
|
||||
|
||||
import { createStore, applyMiddleware, compose } from 'redux';
|
||||
import { applyMiddleware, compose, createStore } from 'redux';
|
||||
import thunk from 'redux-thunk';
|
||||
|
||||
import { QueryLanguageType } from 'ui/embeddable/types';
|
||||
import { DashboardViewMode } from './dashboard/dashboard_view_mode';
|
||||
import { reducers } from './reducers';
|
||||
import { CoreKibanaState } from './selectors';
|
||||
|
||||
const enhancers = [ applyMiddleware(thunk) ];
|
||||
window.__REDUX_DEVTOOLS_EXTENSION__ && enhancers.push(window.__REDUX_DEVTOOLS_EXTENSION__());
|
||||
const enhancers = [applyMiddleware(thunk)];
|
||||
|
||||
export const store = createStore(
|
||||
export const store = createStore<CoreKibanaState>(
|
||||
reducers,
|
||||
{},
|
||||
{
|
||||
dashboard: {
|
||||
embeddables: {},
|
||||
metadata: {
|
||||
title: 'New Dashboard',
|
||||
},
|
||||
panels: {},
|
||||
view: {
|
||||
filters: [],
|
||||
hidePanelTitles: false,
|
||||
isFullScreenMode: false,
|
||||
query: { language: QueryLanguageType.LUCENE, query: '' },
|
||||
timeRange: { from: 'now-15m', to: 'now' },
|
||||
useMargins: true,
|
||||
viewMode: DashboardViewMode.VIEW,
|
||||
},
|
||||
},
|
||||
},
|
||||
compose(...enhancers)
|
||||
);
|
|
@ -28,7 +28,7 @@ export const embeddableShape = PropTypes.shape({
|
|||
render: PropTypes.func.isRequired,
|
||||
});
|
||||
|
||||
interface EmbeddableMetadata {
|
||||
export interface EmbeddableMetadata {
|
||||
// TODO: change to an array, embeddables should be able to specify multiple index patterns they use. Also
|
||||
// see https://github.com/elastic/kibana/issues/19408 - this needs to be generalized to support embeddables that
|
||||
// use dynamic index patterns (vega, TSVB) instead of saved object index patterns (most other visualizations).
|
||||
|
|
|
@ -22,4 +22,10 @@ export * from './embeddable';
|
|||
export {
|
||||
EmbeddableFactoriesRegistryProvider,
|
||||
} from './embeddable_factories_registry';
|
||||
export { ContainerState } from './types';
|
||||
export {
|
||||
ContainerState,
|
||||
EmbeddableState,
|
||||
Query,
|
||||
Filters,
|
||||
TimeRange,
|
||||
} from './types';
|
||||
|
|
|
@ -17,15 +17,38 @@
|
|||
* under the License.
|
||||
*/
|
||||
|
||||
export interface TimeRange {
|
||||
to: string;
|
||||
from: string;
|
||||
}
|
||||
|
||||
// TODO: Filter object representation needs to be fleshed out.
|
||||
export interface Filter {
|
||||
meta: object;
|
||||
query: object;
|
||||
}
|
||||
|
||||
export type Filters = Filter[];
|
||||
|
||||
export enum QueryLanguageType {
|
||||
KUERY = 'kuery',
|
||||
LUCENE = 'lucene',
|
||||
}
|
||||
|
||||
export interface Query {
|
||||
language: QueryLanguageType;
|
||||
query: string;
|
||||
}
|
||||
|
||||
export interface ContainerState {
|
||||
// 'view' or 'edit'. Should probably be an enum but I'm undecided where to define it, here or in dashboard code.
|
||||
viewMode: string;
|
||||
|
||||
timeRange: {
|
||||
// To and From should be either an absolute time range in utc format or a relative one (e.g. now-15m)
|
||||
to: string;
|
||||
from: string;
|
||||
};
|
||||
timeRange: TimeRange;
|
||||
|
||||
filters: Filters;
|
||||
|
||||
query: Query;
|
||||
|
||||
// The shape will be up to the embeddable type.
|
||||
embeddableCustomization?: object;
|
||||
|
@ -42,6 +65,11 @@ export interface ContainerState {
|
|||
* Is the current panel in expanded mode
|
||||
*/
|
||||
isPanelExpanded: boolean;
|
||||
|
||||
/**
|
||||
* A way to override the underlying embeddable title and supply a title at the panel level.
|
||||
*/
|
||||
customTitle: string | undefined;
|
||||
}
|
||||
|
||||
export interface EmbeddableState {
|
||||
|
|
16
yarn.lock
16
yarn.lock
|
@ -275,6 +275,10 @@
|
|||
dependencies:
|
||||
"@types/node" "*"
|
||||
|
||||
"@types/jest@^22.2.3":
|
||||
version "22.2.3"
|
||||
resolved "https://registry.yarnpkg.com/@types/jest/-/jest-22.2.3.tgz#0157c0316dc3722c43a7b71de3fdf3acbccef10d"
|
||||
|
||||
"@types/json-schema@*":
|
||||
version "6.0.1"
|
||||
resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-6.0.1.tgz#a761975746f1c1b2579c62e3a4b5e88f986f7e2e"
|
||||
|
@ -289,6 +293,10 @@
|
|||
dependencies:
|
||||
"@types/node" "*"
|
||||
|
||||
"@types/lodash@^3.10.1":
|
||||
version "3.10.2"
|
||||
resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-3.10.2.tgz#c1fbda1562ef5603c8192fe1fe65b017849d5873"
|
||||
|
||||
"@types/loglevel@^1.5.3":
|
||||
version "1.5.3"
|
||||
resolved "https://registry.yarnpkg.com/@types/loglevel/-/loglevel-1.5.3.tgz#adfce55383edc5998a2170ad581b3e23d6adb5b8"
|
||||
|
@ -340,6 +348,14 @@
|
|||
dependencies:
|
||||
csstype "^2.2.0"
|
||||
|
||||
"@types/redux-actions@^2.2.1":
|
||||
version "2.3.0"
|
||||
resolved "https://registry.yarnpkg.com/@types/redux-actions/-/redux-actions-2.3.0.tgz#d28d7913ec86ee9e20ecb33a1fed887ecb538149"
|
||||
|
||||
"@types/redux@^3.6.31":
|
||||
version "3.6.31"
|
||||
resolved "https://registry.yarnpkg.com/@types/redux/-/redux-3.6.31.tgz#40eafa7575db36b912ce0059b85de98c205b0708"
|
||||
|
||||
"@types/retry@*", "@types/retry@^0.10.2":
|
||||
version "0.10.2"
|
||||
resolved "https://registry.yarnpkg.com/@types/retry/-/retry-0.10.2.tgz#bd1740c4ad51966609b058803ee6874577848b37"
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue