diff --git a/src/core_plugins/kibana/public/dashboard/actions/view.js b/src/core_plugins/kibana/public/dashboard/actions/view.js index 552a7d76c0813..79aa1ca3de96f 100644 --- a/src/core_plugins/kibana/public/dashboard/actions/view.js +++ b/src/core_plugins/kibana/public/dashboard/actions/view.js @@ -5,3 +5,4 @@ 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'); diff --git a/src/core_plugins/kibana/public/dashboard/dashboard_app.js b/src/core_plugins/kibana/public/dashboard/dashboard_app.js index a8c4ceffc8f20..e0d3195fa9f8d 100644 --- a/src/core_plugins/kibana/public/dashboard/dashboard_app.js +++ b/src/core_plugins/kibana/public/dashboard/dashboard_app.js @@ -91,6 +91,7 @@ app.directive('dashboardApp', function ($injector) { $scope.model = { query: dashboardStateManager.getQuery(), useMargins: dashboardStateManager.getUseMargins(), + hidePanelTitles: dashboardStateManager.getHidePanelTitles(), darkTheme: dashboardStateManager.getDarkTheme(), timeRestore: dashboardStateManager.getTimeRestore(), title: dashboardStateManager.getTitle(), @@ -181,6 +182,9 @@ app.directive('dashboardApp', function ($injector) { dashboardStateManager.addNewPanel(hit.id, 'search'); notify.info(`Search successfully added to your dashboard`); }; + $scope.$watch('model.hidePanelTitles', () => { + dashboardStateManager.setHidePanelTitles($scope.model.hidePanelTitles); + }); $scope.$watch('model.useMargins', () => { dashboardStateManager.setUseMargins($scope.model.useMargins); }); diff --git a/src/core_plugins/kibana/public/dashboard/dashboard_container_api.js b/src/core_plugins/kibana/public/dashboard/dashboard_container_api.js index 98a6c7967c3d8..5b5fb276569f4 100644 --- a/src/core_plugins/kibana/public/dashboard/dashboard_container_api.js +++ b/src/core_plugins/kibana/public/dashboard/dashboard_container_api.js @@ -24,4 +24,7 @@ export class DashboardContainerAPI extends ContainerAPI { this.dashboardState.saveState(); } + getHidePanelTitles() { + return this.dashboardState.getHidePanelTitles(); + } } diff --git a/src/core_plugins/kibana/public/dashboard/dashboard_state_manager.js b/src/core_plugins/kibana/public/dashboard/dashboard_state_manager.js index 669007e3615c2..b906aebd54eb5 100644 --- a/src/core_plugins/kibana/public/dashboard/dashboard_state_manager.js +++ b/src/core_plugins/kibana/public/dashboard/dashboard_state_manager.js @@ -13,6 +13,7 @@ import { minimizePanel, updateTitle, updateDescription, + updateHidePanelTitles, } from './actions'; import { stateMonitorFactory } from 'ui/state_management/state_monitor_factory'; import { createPanelState, getPersistedStateId } from './panel'; @@ -25,6 +26,7 @@ import { getTitle, getDescription, getUseMargins, + getHidePanelTitles, } from '../selectors'; /** @@ -85,6 +87,7 @@ export class DashboardStateManager { store.dispatch(setPanels(this.getPanels())); store.dispatch(updateViewMode(this.getViewMode())); store.dispatch(updateUseMargins(this.getUseMargins())); + store.dispatch(updateHidePanelTitles(this.getHidePanelTitles())); store.dispatch(updateIsFullScreenMode(this.getFullScreenMode())); store.dispatch(updateTitle(this.getTitle())); store.dispatch(updateDescription(this.getDescription())); @@ -138,6 +141,10 @@ export class DashboardStateManager { store.dispatch(updateUseMargins(this.getUseMargins())); } + if (getHidePanelTitles(state) !== this.getHidePanelTitles()) { + store.dispatch(updateHidePanelTitles(this.getHidePanelTitles())); + } + if (getFullScreenMode(state) !== this.getFullScreenMode()) { store.dispatch(updateIsFullScreenMode(this.getFullScreenMode())); } @@ -270,6 +277,15 @@ export class DashboardStateManager { this.saveState(); } + getHidePanelTitles() { + return this.appState.options.hidePanelTitles; + } + + setHidePanelTitles(hidePanelTitles) { + this.appState.options.hidePanelTitles = hidePanelTitles; + this.saveState(); + } + getDarkTheme() { return this.appState.options.darkTheme; } diff --git a/src/core_plugins/kibana/public/dashboard/panel/panel_header/panel_header.js b/src/core_plugins/kibana/public/dashboard/panel/panel_header/panel_header.js index 2d15633c69e9a..b61f3b4a77688 100644 --- a/src/core_plugins/kibana/public/dashboard/panel/panel_header/panel_header.js +++ b/src/core_plugins/kibana/public/dashboard/panel/panel_header/panel_header.js @@ -1,8 +1,8 @@ import React from 'react'; import PropTypes from 'prop-types'; -export function PanelHeader({ title, actions, isViewOnlyMode }) { - if (isViewOnlyMode && !title) { +export function PanelHeader({ title, actions, isViewOnlyMode, hidePanelTitles }) { + if (isViewOnlyMode && (!title || hidePanelTitles)) { return (
@@ -20,7 +20,7 @@ export function PanelHeader({ title, actions, isViewOnlyMode }) { title={title} aria-label={`Dashboard panel: ${title}`} > - {title} + {hidePanelTitles ? '' : title}
@@ -34,4 +34,5 @@ PanelHeader.propTypes = { isViewOnlyMode: PropTypes.bool, title: PropTypes.string, actions: PropTypes.node, + hidePanelTitles: PropTypes.bool.isRequired, }; diff --git a/src/core_plugins/kibana/public/dashboard/panel/panel_header/panel_header_container.js b/src/core_plugins/kibana/public/dashboard/panel/panel_header/panel_header_container.js index b31dc3bd1dfc0..6199b0b07c2d1 100644 --- a/src/core_plugins/kibana/public/dashboard/panel/panel_header/panel_header_container.js +++ b/src/core_plugins/kibana/public/dashboard/panel/panel_header/panel_header_container.js @@ -18,7 +18,8 @@ import { getPanel, getMaximizedPanelId, getFullScreenMode, - getViewMode + getViewMode, + getHidePanelTitles, } from '../../selectors'; const mapStateToProps = ({ dashboard }, { panelId }) => { @@ -29,6 +30,7 @@ const mapStateToProps = ({ dashboard }, { panelId }) => { title: panel.title === undefined ? embeddableTitle : panel.title, isExpanded: getMaximizedPanelId(dashboard) === panelId, isViewOnlyMode: getFullScreenMode(dashboard) || getViewMode(dashboard) === DashboardViewMode.VIEW, + hidePanelTitles: getHidePanelTitles(dashboard), }; }; @@ -38,7 +40,7 @@ const mapDispatchToProps = (dispatch, { panelId }) => ({ }); const mergeProps = (stateProps, dispatchProps, ownProps) => { - const { isExpanded, isViewOnlyMode, title } = stateProps; + const { isExpanded, isViewOnlyMode, title, hidePanelTitles } = stateProps; const { onMaximizePanel, onMinimizePanel } = dispatchProps; const { panelId, embeddableFactory } = ownProps; let actions; @@ -60,6 +62,7 @@ const mergeProps = (stateProps, dispatchProps, ownProps) => { title, actions, isViewOnlyMode, + hidePanelTitles, }; }; diff --git a/src/core_plugins/kibana/public/dashboard/reducers/view.js b/src/core_plugins/kibana/public/dashboard/reducers/view.js index 77d69b12e7ccb..744e3df8bce97 100644 --- a/src/core_plugins/kibana/public/dashboard/reducers/view.js +++ b/src/core_plugins/kibana/public/dashboard/reducers/view.js @@ -4,6 +4,7 @@ import { maximizePanel, minimizePanel, updateUseMargins, + updateHidePanelTitles, updateIsFullScreenMode, } from '../actions'; @@ -20,6 +21,11 @@ export const view = handleActions({ useMargins: payload }), + [updateHidePanelTitles]: (state, { payload }) => ({ + ...state, + hidePanelTitles: payload + }), + [combineActions(maximizePanel, minimizePanel)]: (state, { payload }) => ({ ...state, maximizedPanelId: payload @@ -34,4 +40,5 @@ export const view = handleActions({ viewMode: DashboardViewMode.VIEW, maximizedPanelId: undefined, useMargins: true, + hidePanelTitles: false, }); diff --git a/src/core_plugins/kibana/public/dashboard/saved_dashboard/saved_dashboard.js b/src/core_plugins/kibana/public/dashboard/saved_dashboard/saved_dashboard.js index 0bc856f672f4f..71aa3df4ddead 100644 --- a/src/core_plugins/kibana/public/dashboard/saved_dashboard/saved_dashboard.js +++ b/src/core_plugins/kibana/public/dashboard/saved_dashboard/saved_dashboard.js @@ -28,6 +28,7 @@ module.factory('SavedDashboard', function (courier, config) { darkTheme: config.get('dashboard:defaultDarkTheme'), // for BWC reasons we can't default dashboards that already exist without this setting to true. useMargins: id ? false : true, + hidePanelTitles: false, }), uiStateJSON: '{}', version: 1, diff --git a/src/core_plugins/kibana/public/dashboard/selectors/index.js b/src/core_plugins/kibana/public/dashboard/selectors/index.js index 19acdf6a5dc35..5570722c0d31b 100644 --- a/src/core_plugins/kibana/public/dashboard/selectors/index.js +++ b/src/core_plugins/kibana/public/dashboard/selectors/index.js @@ -79,6 +79,11 @@ export const getViewMode = dashboard => dashboard.view.viewMode; * @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} diff --git a/src/core_plugins/kibana/public/dashboard/top_nav/options.html b/src/core_plugins/kibana/public/dashboard/top_nav/options.html index d13f2cf9bb3c6..b81859c79b0f0 100644 --- a/src/core_plugins/kibana/public/dashboard/top_nav/options.html +++ b/src/core_plugins/kibana/public/dashboard/top_nav/options.html @@ -29,5 +29,17 @@

Use margins between panels +

diff --git a/src/core_plugins/kibana/public/discover/embeddable/search_embeddable_factory.js b/src/core_plugins/kibana/public/discover/embeddable/search_embeddable_factory.js index 127694bbcde92..7132c7312dd63 100644 --- a/src/core_plugins/kibana/public/discover/embeddable/search_embeddable_factory.js +++ b/src/core_plugins/kibana/public/discover/embeddable/search_embeddable_factory.js @@ -31,7 +31,9 @@ export class SearchEmbeddableFactory extends EmbeddableFactory { searchScope.editPath = this.getEditPath(panel.id); return this.searchLoader.get(panel.id) .then(savedObject => { - searchScope.sharedItemTitle = panel.title !== undefined ? panel.title : savedObject.title; + if (!container.getHidePanelTitles()) { + searchScope.sharedItemTitle = panel.title !== undefined ? panel.title : savedObject.title; + } searchScope.savedObj = savedObject; searchScope.panel = panel; container.registerPanelIndexPattern(panel.panelIndex, savedObject.searchSource.get('index')); diff --git a/src/core_plugins/kibana/public/selectors/dashboard_selectors.js b/src/core_plugins/kibana/public/selectors/dashboard_selectors.js index 0784840d17bac..706f4feec7bb8 100644 --- a/src/core_plugins/kibana/public/selectors/dashboard_selectors.js +++ b/src/core_plugins/kibana/public/selectors/dashboard_selectors.js @@ -24,6 +24,7 @@ export const getViewMode = state => DashboardSelectors.getViewMode(getDashboard( 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 getTitle = state => DashboardSelectors.getTitle(getDashboard(state)); export const getDescription = state => DashboardSelectors.getDescription(getDashboard(state)); diff --git a/src/core_plugins/kibana/public/visualize/embeddable/visualize_embeddable_factory.js b/src/core_plugins/kibana/public/visualize/embeddable/visualize_embeddable_factory.js index 06f403e4d8293..770c79d46ca40 100644 --- a/src/core_plugins/kibana/public/visualize/embeddable/visualize_embeddable_factory.js +++ b/src/core_plugins/kibana/public/visualize/embeddable/visualize_embeddable_factory.js @@ -30,7 +30,9 @@ export class VisualizeEmbeddableFactory extends EmbeddableFactory { visualizeScope.editUrl = this.getEditPath(panel.id); return this.visualizeLoader.get(panel.id) .then(savedObject => { - visualizeScope.sharedItemTitle = panel.title !== undefined ? panel.title : savedObject.title; + if (!container.getHidePanelTitles()) { + visualizeScope.sharedItemTitle = panel.title !== undefined ? panel.title : savedObject.title; + } visualizeScope.savedObj = savedObject; visualizeScope.panel = panel; diff --git a/src/ui/public/embeddable/container_api.js b/src/ui/public/embeddable/container_api.js index e1471a88d7a70..098f9784e29cf 100644 --- a/src/ui/public/embeddable/container_api.js +++ b/src/ui/public/embeddable/container_api.js @@ -48,4 +48,8 @@ export class ContainerAPI { updatePanel(/*paneIndex, panelAttributes */) { throw new Error('Must implement updatePanel.'); } + + getHidePanelTitles() { + return this.dashboardState.getHidePanelTitles(); + } }