Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

[7.x] Add embed mode options in the Share UI (#58435) #68503

Merged
merged 1 commit into from
Jun 8, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 0 additions & 4 deletions src/legacy/ui/public/styles/_legacy/_base.scss
Original file line number Diff line number Diff line change
Expand Up @@ -64,10 +64,6 @@ input[type='checkbox'],
padding-bottom: $euiSizeS;
}

.globalQueryBar {
padding: 0px $euiSizeS $euiSizeS $euiSizeS;
}

> nav,
> navbar {
z-index: 2 !important;
Expand Down
143 changes: 131 additions & 12 deletions src/plugins/dashboard/public/application/dashboard_app_controller.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,9 @@

import _, { uniq } from 'lodash';
import { i18n } from '@kbn/i18n';
import { EUI_MODAL_CANCEL_BUTTON } from '@elastic/eui';
import React from 'react';
import { EUI_MODAL_CANCEL_BUTTON, EuiCheckboxGroup } from '@elastic/eui';
import { EuiCheckboxGroupIdToSelectedMap } from '@elastic/eui/src/components/form/checkbox/checkbox_group';
import React, { useState, ReactElement } from 'react';
import ReactDOM from 'react-dom';
import angular from 'angular';

Expand Down Expand Up @@ -94,6 +95,25 @@ export interface DashboardAppControllerDependencies extends RenderDeps {
navigation: NavigationStart;
}

enum UrlParams {
SHOW_TOP_MENU = 'show-top-menu',
SHOW_QUERY_INPUT = 'show-query-input',
SHOW_TIME_FILTER = 'show-time-filter',
SHOW_FILTER_BAR = 'show-filter-bar',
HIDE_FILTER_BAR = 'hide-filter-bar',
}

interface UrlParamsSelectedMap {
[UrlParams.SHOW_TOP_MENU]: boolean;
[UrlParams.SHOW_QUERY_INPUT]: boolean;
[UrlParams.SHOW_TIME_FILTER]: boolean;
[UrlParams.SHOW_FILTER_BAR]: boolean;
}

interface UrlParamValues extends Omit<UrlParamsSelectedMap, UrlParams.SHOW_FILTER_BAR> {
[UrlParams.HIDE_FILTER_BAR]: boolean;
}

export class DashboardAppController {
// Part of the exposed plugin API - do not remove without careful consideration.
appStatus: {
Expand Down Expand Up @@ -133,8 +153,16 @@ export class DashboardAppController {
const filterManager = queryService.filterManager;
const queryFilter = filterManager;
const timefilter = queryService.timefilter.timefilter;
let showSearchBar = true;
let showQueryBar = true;
const isEmbeddedExternally = Boolean($routeParams.embed);

// url param rules should only apply when embedded (e.g. url?embed=true)
const shouldForceDisplay = (param: string): boolean =>
isEmbeddedExternally && Boolean($routeParams[param]);

const forceShowTopNavMenu = shouldForceDisplay(UrlParams.SHOW_TOP_MENU);
const forceShowQueryInput = shouldForceDisplay(UrlParams.SHOW_QUERY_INPUT);
const forceShowDatePicker = shouldForceDisplay(UrlParams.SHOW_TIME_FILTER);
const forceHideFilterBar = shouldForceDisplay(UrlParams.HIDE_FILTER_BAR);

let lastReloadRequestTime = 0;
const dash = ($scope.dash = $route.current.locals.dash);
Expand Down Expand Up @@ -251,9 +279,6 @@ export class DashboardAppController {
}
};

const showFilterBar = () =>
$scope.model.filters.length > 0 || !dashboardStateManager.getFullScreenMode();

const getEmptyScreenProps = (
shouldShowEditHelp: boolean,
isEmptyInReadOnlyMode: boolean
Expand Down Expand Up @@ -299,6 +324,7 @@ export class DashboardAppController {
viewMode: dashboardStateManager.getViewMode(),
panels: embeddablesMap,
isFullScreenMode: dashboardStateManager.getFullScreenMode(),
isEmbeddedExternally,
isEmptyState: shouldShowEditHelp || shouldShowViewHelp || isEmptyInReadonlyMode,
useMargins: dashboardStateManager.getUseMargins(),
lastReloadRequestTime,
Expand Down Expand Up @@ -590,17 +616,33 @@ export class DashboardAppController {
dashboardStateManager.setSavedQueryId(savedQueryId);
};

const shouldShowFilterBar = (forceHide: boolean): boolean =>
!forceHide && ($scope.model.filters.length > 0 || !dashboardStateManager.getFullScreenMode());

const shouldShowNavBarComponent = (forceShow: boolean): boolean =>
(forceShow || $scope.isVisible) && !dashboardStateManager.getFullScreenMode();

const getNavBarProps = () => {
const isFullScreenMode = dashboardStateManager.getFullScreenMode();
const screenTitle = dashboardStateManager.getTitle();
const showTopNavMenu = shouldShowNavBarComponent(forceShowTopNavMenu);
const showQueryInput = shouldShowNavBarComponent(forceShowQueryInput);
const showDatePicker = shouldShowNavBarComponent(forceShowDatePicker);
const showQueryBar = showQueryInput || showDatePicker;
const showFilterBar = shouldShowFilterBar(forceHideFilterBar);
const showSearchBar = showQueryBar || showFilterBar;

return {
appName: 'dashboard',
config: $scope.isVisible ? $scope.topNavMenu : undefined,
config: showTopNavMenu ? $scope.topNavMenu : undefined,
className: isFullScreenMode ? 'kbnTopNavMenu-isFullScreen' : undefined,
screenTitle,
showTopNavMenu,
showSearchBar,
showQueryBar,
showFilterBar: showFilterBar(),
showQueryInput,
showDatePicker,
showFilterBar,
indexPatterns: $scope.indexPatterns,
showSaveQuery: $scope.showSaveQuery,
query: $scope.model.query,
Expand Down Expand Up @@ -798,7 +840,6 @@ export class DashboardAppController {
} = {};
navActions[TopNavIds.FULL_SCREEN] = () => {
dashboardStateManager.setFullScreenMode(true);
showQueryBar = false;
updateNavBar();
};
navActions[TopNavIds.EXIT_EDIT_MODE] = () => onChangeViewMode(ViewMode.VIEW);
Expand Down Expand Up @@ -923,6 +964,80 @@ export class DashboardAppController {
if (share) {
// the share button is only availabale if "share" plugin contract enabled
navActions[TopNavIds.SHARE] = (anchorElement) => {
const EmbedUrlParamExtension = ({
setParamValue,
}: {
setParamValue: (paramUpdate: UrlParamValues) => void;
}): ReactElement => {
const [urlParamsSelectedMap, setUrlParamsSelectedMap] = useState<UrlParamsSelectedMap>({
[UrlParams.SHOW_TOP_MENU]: false,
[UrlParams.SHOW_QUERY_INPUT]: false,
[UrlParams.SHOW_TIME_FILTER]: false,
[UrlParams.SHOW_FILTER_BAR]: true,
});

const checkboxes = [
{
id: UrlParams.SHOW_TOP_MENU,
label: i18n.translate('dashboard.embedUrlParamExtension.topMenu', {
defaultMessage: 'Top menu',
}),
},
{
id: UrlParams.SHOW_QUERY_INPUT,
label: i18n.translate('dashboard.embedUrlParamExtension.query', {
defaultMessage: 'Query',
}),
},
{
id: UrlParams.SHOW_TIME_FILTER,
label: i18n.translate('dashboard.embedUrlParamExtension.timeFilter', {
defaultMessage: 'Time filter',
}),
},
{
id: UrlParams.SHOW_FILTER_BAR,
label: i18n.translate('dashboard.embedUrlParamExtension.filterBar', {
defaultMessage: 'Filter bar',
}),
},
];

const handleChange = (param: string): void => {
const urlParamsSelectedMapUpdate = {
...urlParamsSelectedMap,
[param]: !urlParamsSelectedMap[param as keyof UrlParamsSelectedMap],
};
setUrlParamsSelectedMap(urlParamsSelectedMapUpdate);

const urlParamValues = {
[UrlParams.SHOW_TOP_MENU]: urlParamsSelectedMap[UrlParams.SHOW_TOP_MENU],
[UrlParams.SHOW_QUERY_INPUT]: urlParamsSelectedMap[UrlParams.SHOW_QUERY_INPUT],
[UrlParams.SHOW_TIME_FILTER]: urlParamsSelectedMap[UrlParams.SHOW_TIME_FILTER],
[UrlParams.HIDE_FILTER_BAR]: !urlParamsSelectedMap[UrlParams.SHOW_FILTER_BAR],
[param === UrlParams.SHOW_FILTER_BAR ? UrlParams.HIDE_FILTER_BAR : param]:
param === UrlParams.SHOW_FILTER_BAR
? urlParamsSelectedMap[UrlParams.SHOW_FILTER_BAR]
: !urlParamsSelectedMap[param as keyof UrlParamsSelectedMap],
};
setParamValue(urlParamValues);
};

return (
<EuiCheckboxGroup
options={checkboxes}
idToSelectedMap={(urlParamsSelectedMap as unknown) as EuiCheckboxGroupIdToSelectedMap}
onChange={handleChange}
legend={{
children: i18n.translate('dashboard.embedUrlParamExtension.include', {
defaultMessage: 'Include',
}),
}}
data-test-subj="embedUrlParamExtension"
/>
);
};

share.toggleShareContextMenu({
anchorElement,
allowEmbed: true,
Expand All @@ -935,6 +1050,12 @@ export class DashboardAppController {
title: dash.title,
},
isDirty: dashboardStateManager.getIsDirty(),
embedUrlParamExtensions: [
{
paramName: 'embed',
component: EmbedUrlParamExtension,
},
],
});
};
}
Expand All @@ -955,8 +1076,6 @@ export class DashboardAppController {
const visibleSubscription = chrome.getIsVisible$().subscribe((isVisible) => {
$scope.$evalAsync(() => {
$scope.isVisible = isVisible;
showSearchBar = isVisible || showFilterBar();
showQueryBar = !dashboardStateManager.getFullScreenMode() && isVisible;
updateNavBar();
});
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ export interface DashboardContainerInput extends ContainerInput {
useMargins: boolean;
title: string;
description?: string;
isEmbeddedExternally: boolean;
isFullScreenMode: boolean;
panels: {
[panelId: string]: DashboardPanelState<EmbeddableInput & { [k: string]: unknown }>;
Expand Down Expand Up @@ -105,6 +106,7 @@ export class DashboardContainer extends Container<InheritedChildInput, Dashboard
super(
{
panels: {},
isEmbeddedExternally: false,
isFullScreenMode: false,
filters: [],
useMargins: true,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ export class DashboardContainerFactory
public getDefaultInput(): Partial<DashboardContainerInput> {
return {
panels: {},
isEmbeddedExternally: false,
isFullScreenMode: false,
useMargins: true,
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ interface State {
title: string;
description?: string;
panels: { [key: string]: PanelState };
isEmbeddedExternally?: boolean;
isEmptyState?: boolean;
}

Expand All @@ -51,6 +52,7 @@ export class DashboardViewport extends React.Component<DashboardViewportProps, S
panels,
useMargins,
title,
isEmbeddedExternally,
isEmptyState,
} = this.props.container.getInput();

Expand All @@ -59,6 +61,7 @@ export class DashboardViewport extends React.Component<DashboardViewportProps, S
panels,
useMargins,
title,
isEmbeddedExternally,
isEmptyState,
};
}
Expand All @@ -71,6 +74,7 @@ export class DashboardViewport extends React.Component<DashboardViewportProps, S
useMargins,
title,
description,
isEmbeddedExternally,
isEmptyState,
} = this.props.container.getInput();
if (this.mounted) {
Expand All @@ -79,6 +83,7 @@ export class DashboardViewport extends React.Component<DashboardViewportProps, S
description,
useMargins,
title,
isEmbeddedExternally,
isEmptyState,
});
}
Expand All @@ -100,12 +105,13 @@ export class DashboardViewport extends React.Component<DashboardViewportProps, S

private renderEmptyScreen() {
const { renderEmpty } = this.props;
const { isFullScreenMode } = this.state;
const { isEmbeddedExternally, isFullScreenMode } = this.state;
return (
<div className="dshDashboardEmptyScreen">
{isFullScreenMode && (
<this.context.services.ExitFullScreenButton
onExitFullScreenMode={this.onExitFullScreenMode}
toggleChrome={!isEmbeddedExternally}
/>
)}
{renderEmpty && renderEmpty()}
Expand All @@ -115,7 +121,14 @@ export class DashboardViewport extends React.Component<DashboardViewportProps, S

private renderContainerScreen() {
const { container } = this.props;
const { isFullScreenMode, panels, title, description, useMargins } = this.state;
const {
isEmbeddedExternally,
isFullScreenMode,
panels,
title,
description,
useMargins,
} = this.state;
return (
<div
data-shared-items-count={Object.values(panels).length}
Expand All @@ -127,6 +140,7 @@ export class DashboardViewport extends React.Component<DashboardViewportProps, S
{isFullScreenMode && (
<this.context.services.ExitFullScreenButton
onExitFullScreenMode={this.onExitFullScreenMode}
toggleChrome={!isEmbeddedExternally}
/>
)}
<DashboardGrid container={container} />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ export function getSampleDashboardInput(
id: '123',
filters: [],
useMargins: false,
isEmbeddedExternally: false,
isFullScreenMode: false,
title: 'My Dashboard',
query: {
Expand Down
23 changes: 17 additions & 6 deletions src/plugins/dashboard/public/plugin.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -167,15 +167,26 @@ export class DashboardPlugin
const getStartServices = async () => {
const [coreStart, deps] = await core.getStartServices();

const useHideChrome = () => {
const useHideChrome = ({ toggleChrome } = { toggleChrome: true }) => {
React.useEffect(() => {
coreStart.chrome.setIsVisible(false);
return () => coreStart.chrome.setIsVisible(true);
}, []);
if (toggleChrome) {
coreStart.chrome.setIsVisible(false);
}

return () => {
if (toggleChrome) {
coreStart.chrome.setIsVisible(true);
}
};
}, [toggleChrome]);
};

const ExitFullScreenButton: React.FC<ExitFullScreenButtonProps> = (props) => {
useHideChrome();
const ExitFullScreenButton: React.FC<
ExitFullScreenButtonProps & {
toggleChrome: boolean;
}
> = ({ toggleChrome, ...props }) => {
useHideChrome({ toggleChrome });
return <ExitFullScreenButtonUi {...props} />;
};
return {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@
padding: 0px $euiSizeS $euiSizeS $euiSizeS;
}

.globalQueryBar:first-child {
padding-top: $euiSizeS;
}

.globalQueryBar:not(:empty) {
padding-bottom: $euiSizeS;
}
Expand Down
Loading