mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 09:48:58 -04:00
parent
65ec264bbf
commit
823ce6453f
19 changed files with 564 additions and 71 deletions
|
@ -64,10 +64,6 @@ input[type='checkbox'],
|
|||
padding-bottom: $euiSizeS;
|
||||
}
|
||||
|
||||
.globalQueryBar {
|
||||
padding: 0px $euiSizeS $euiSizeS $euiSizeS;
|
||||
}
|
||||
|
||||
> nav,
|
||||
> navbar {
|
||||
z-index: 2 !important;
|
||||
|
|
|
@ -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';
|
||||
|
||||
|
@ -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: {
|
||||
|
@ -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);
|
||||
|
@ -251,9 +279,6 @@ export class DashboardAppController {
|
|||
}
|
||||
};
|
||||
|
||||
const showFilterBar = () =>
|
||||
$scope.model.filters.length > 0 || !dashboardStateManager.getFullScreenMode();
|
||||
|
||||
const getEmptyScreenProps = (
|
||||
shouldShowEditHelp: boolean,
|
||||
isEmptyInReadOnlyMode: boolean
|
||||
|
@ -299,6 +324,7 @@ export class DashboardAppController {
|
|||
viewMode: dashboardStateManager.getViewMode(),
|
||||
panels: embeddablesMap,
|
||||
isFullScreenMode: dashboardStateManager.getFullScreenMode(),
|
||||
isEmbeddedExternally,
|
||||
isEmptyState: shouldShowEditHelp || shouldShowViewHelp || isEmptyInReadonlyMode,
|
||||
useMargins: dashboardStateManager.getUseMargins(),
|
||||
lastReloadRequestTime,
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
|
@ -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,
|
||||
|
@ -935,6 +1050,12 @@ export class DashboardAppController {
|
|||
title: dash.title,
|
||||
},
|
||||
isDirty: dashboardStateManager.getIsDirty(),
|
||||
embedUrlParamExtensions: [
|
||||
{
|
||||
paramName: 'embed',
|
||||
component: EmbedUrlParamExtension,
|
||||
},
|
||||
],
|
||||
});
|
||||
};
|
||||
}
|
||||
|
@ -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();
|
||||
});
|
||||
});
|
||||
|
|
|
@ -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 }>;
|
||||
|
@ -105,6 +106,7 @@ export class DashboardContainer extends Container<InheritedChildInput, Dashboard
|
|||
super(
|
||||
{
|
||||
panels: {},
|
||||
isEmbeddedExternally: false,
|
||||
isFullScreenMode: false,
|
||||
filters: [],
|
||||
useMargins: true,
|
||||
|
|
|
@ -65,6 +65,7 @@ export class DashboardContainerFactory
|
|||
public getDefaultInput(): Partial<DashboardContainerInput> {
|
||||
return {
|
||||
panels: {},
|
||||
isEmbeddedExternally: false,
|
||||
isFullScreenMode: false,
|
||||
useMargins: true,
|
||||
};
|
||||
|
|
|
@ -35,6 +35,7 @@ interface State {
|
|||
title: string;
|
||||
description?: string;
|
||||
panels: { [key: string]: PanelState };
|
||||
isEmbeddedExternally?: boolean;
|
||||
isEmptyState?: boolean;
|
||||
}
|
||||
|
||||
|
@ -51,6 +52,7 @@ export class DashboardViewport extends React.Component<DashboardViewportProps, S
|
|||
panels,
|
||||
useMargins,
|
||||
title,
|
||||
isEmbeddedExternally,
|
||||
isEmptyState,
|
||||
} = this.props.container.getInput();
|
||||
|
||||
|
@ -59,6 +61,7 @@ export class DashboardViewport extends React.Component<DashboardViewportProps, S
|
|||
panels,
|
||||
useMargins,
|
||||
title,
|
||||
isEmbeddedExternally,
|
||||
isEmptyState,
|
||||
};
|
||||
}
|
||||
|
@ -71,6 +74,7 @@ export class DashboardViewport extends React.Component<DashboardViewportProps, S
|
|||
useMargins,
|
||||
title,
|
||||
description,
|
||||
isEmbeddedExternally,
|
||||
isEmptyState,
|
||||
} = this.props.container.getInput();
|
||||
if (this.mounted) {
|
||||
|
@ -79,6 +83,7 @@ export class DashboardViewport extends React.Component<DashboardViewportProps, S
|
|||
description,
|
||||
useMargins,
|
||||
title,
|
||||
isEmbeddedExternally,
|
||||
isEmptyState,
|
||||
});
|
||||
}
|
||||
|
@ -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()}
|
||||
|
@ -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}
|
||||
|
@ -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} />
|
||||
|
|
|
@ -27,6 +27,7 @@ export function getSampleDashboardInput(
|
|||
id: '123',
|
||||
filters: [],
|
||||
useMargins: false,
|
||||
isEmbeddedExternally: false,
|
||||
isFullScreenMode: false,
|
||||
title: 'My Dashboard',
|
||||
query: {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -3,6 +3,10 @@
|
|||
padding: 0px $euiSizeS $euiSizeS $euiSizeS;
|
||||
}
|
||||
|
||||
.globalQueryBar:first-child {
|
||||
padding-top: $euiSizeS;
|
||||
}
|
||||
|
||||
.globalQueryBar:not(:empty) {
|
||||
padding-bottom: $euiSizeS;
|
||||
}
|
||||
|
|
|
@ -94,11 +94,11 @@ export const createTopNavHelper = ({ TopNavMenu }) => (reactDirective) => {
|
|||
// All modifiers default to true.
|
||||
// Set to false to hide subcomponents.
|
||||
'showSearchBar',
|
||||
'showFilterBar',
|
||||
'showQueryBar',
|
||||
'showQueryInput',
|
||||
'showDatePicker',
|
||||
'showSaveQuery',
|
||||
'showDatePicker',
|
||||
'showFilterBar',
|
||||
|
||||
'appName',
|
||||
'screenTitle',
|
||||
|
|
|
@ -29,6 +29,7 @@ const dataShim = {
|
|||
};
|
||||
|
||||
describe('TopNavMenu', () => {
|
||||
const WRAPPER_SELECTOR = '.kbnTopNavMenu__wrapper';
|
||||
const TOP_NAV_ITEM_SELECTOR = 'TopNavMenuItem';
|
||||
const SEARCH_BAR_SELECTOR = 'SearchBar';
|
||||
const menuItems: TopNavMenuData[] = [
|
||||
|
@ -51,18 +52,28 @@ describe('TopNavMenu', () => {
|
|||
|
||||
it('Should render nothing when no config is provided', () => {
|
||||
const component = shallowWithIntl(<TopNavMenu appName={'test'} />);
|
||||
expect(component.find(WRAPPER_SELECTOR).length).toBe(0);
|
||||
expect(component.find(TOP_NAV_ITEM_SELECTOR).length).toBe(0);
|
||||
expect(component.find(SEARCH_BAR_SELECTOR).length).toBe(0);
|
||||
});
|
||||
|
||||
it('Should not render menu items when config is empty', () => {
|
||||
const component = shallowWithIntl(<TopNavMenu appName={'test'} config={[]} />);
|
||||
expect(component.find(WRAPPER_SELECTOR).length).toBe(0);
|
||||
expect(component.find(TOP_NAV_ITEM_SELECTOR).length).toBe(0);
|
||||
expect(component.find(SEARCH_BAR_SELECTOR).length).toBe(0);
|
||||
});
|
||||
|
||||
it('Should render 1 menu item', () => {
|
||||
const component = shallowWithIntl(<TopNavMenu appName={'test'} config={[menuItems[0]]} />);
|
||||
expect(component.find(WRAPPER_SELECTOR).length).toBe(1);
|
||||
expect(component.find(TOP_NAV_ITEM_SELECTOR).length).toBe(1);
|
||||
expect(component.find(SEARCH_BAR_SELECTOR).length).toBe(0);
|
||||
});
|
||||
|
||||
it('Should render multiple menu items', () => {
|
||||
const component = shallowWithIntl(<TopNavMenu appName={'test'} config={menuItems} />);
|
||||
expect(component.find(WRAPPER_SELECTOR).length).toBe(1);
|
||||
expect(component.find(TOP_NAV_ITEM_SELECTOR).length).toBe(menuItems.length);
|
||||
expect(component.find(SEARCH_BAR_SELECTOR).length).toBe(0);
|
||||
});
|
||||
|
@ -71,15 +82,25 @@ describe('TopNavMenu', () => {
|
|||
const component = shallowWithIntl(
|
||||
<TopNavMenu appName={'test'} showSearchBar={true} data={dataShim as any} />
|
||||
);
|
||||
|
||||
expect(component.find(WRAPPER_SELECTOR).length).toBe(1);
|
||||
expect(component.find(TOP_NAV_ITEM_SELECTOR).length).toBe(0);
|
||||
expect(component.find(SEARCH_BAR_SELECTOR).length).toBe(1);
|
||||
});
|
||||
|
||||
it('Should render menu items and search bar', () => {
|
||||
const component = shallowWithIntl(
|
||||
<TopNavMenu appName={'test'} config={menuItems} showSearchBar={true} data={dataShim as any} />
|
||||
);
|
||||
expect(component.find(WRAPPER_SELECTOR).length).toBe(1);
|
||||
expect(component.find(TOP_NAV_ITEM_SELECTOR).length).toBe(menuItems.length);
|
||||
expect(component.find(SEARCH_BAR_SELECTOR).length).toBe(1);
|
||||
});
|
||||
|
||||
it('Should render with a class name', () => {
|
||||
const component = shallowWithIntl(
|
||||
<TopNavMenu
|
||||
appName={'test'}
|
||||
config={menuItems}
|
||||
showSearchBar={true}
|
||||
data={dataShim as any}
|
||||
className={'myCoolClass'}
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
* under the License.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import React, { ReactElement } from 'react';
|
||||
|
||||
import { EuiFlexGroup, EuiFlexItem } from '@elastic/eui';
|
||||
|
||||
|
@ -29,6 +29,10 @@ import { StatefulSearchBarProps, DataPublicPluginStart } from '../../../data/pub
|
|||
export type TopNavMenuProps = StatefulSearchBarProps & {
|
||||
config?: TopNavMenuData[];
|
||||
showSearchBar?: boolean;
|
||||
showQueryBar?: boolean;
|
||||
showQueryInput?: boolean;
|
||||
showDatePicker?: boolean;
|
||||
showFilterBar?: boolean;
|
||||
data?: DataPublicPluginStart;
|
||||
className?: string;
|
||||
};
|
||||
|
@ -42,10 +46,15 @@ export type TopNavMenuProps = StatefulSearchBarProps & {
|
|||
*
|
||||
**/
|
||||
|
||||
export function TopNavMenu(props: TopNavMenuProps) {
|
||||
export function TopNavMenu(props: TopNavMenuProps): ReactElement | null {
|
||||
const { config, showSearchBar, ...searchBarProps } = props;
|
||||
function renderItems() {
|
||||
if (!config) return;
|
||||
|
||||
if ((!config || config.length === 0) && (!showSearchBar || !props.data)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
function renderItems(): ReactElement[] | null {
|
||||
if (!config || config.length === 0) return null;
|
||||
return config.map((menuItem: TopNavMenuData, i: number) => {
|
||||
return (
|
||||
<EuiFlexItem
|
||||
|
@ -59,9 +68,25 @@ export function TopNavMenu(props: TopNavMenuProps) {
|
|||
});
|
||||
}
|
||||
|
||||
function renderSearchBar() {
|
||||
function renderMenu(className: string): ReactElement | null {
|
||||
if (!config || config.length === 0) return null;
|
||||
return (
|
||||
<EuiFlexGroup
|
||||
data-test-subj="top-nav"
|
||||
justifyContent="flexStart"
|
||||
alignItems="center"
|
||||
gutterSize="none"
|
||||
className={className}
|
||||
responsive={false}
|
||||
>
|
||||
{renderItems()}
|
||||
</EuiFlexGroup>
|
||||
);
|
||||
}
|
||||
|
||||
function renderSearchBar(): ReactElement | null {
|
||||
// Validate presense of all required fields
|
||||
if (!showSearchBar || !props.data) return;
|
||||
if (!showSearchBar || !props.data) return null;
|
||||
const { SearchBar } = props.data.ui;
|
||||
return <SearchBar {...searchBarProps} />;
|
||||
}
|
||||
|
@ -70,16 +95,7 @@ export function TopNavMenu(props: TopNavMenuProps) {
|
|||
const className = classNames('kbnTopNavMenu', props.className);
|
||||
return (
|
||||
<span className="kbnTopNavMenu__wrapper">
|
||||
<EuiFlexGroup
|
||||
data-test-subj="top-nav"
|
||||
justifyContent="flexStart"
|
||||
alignItems="center"
|
||||
gutterSize="none"
|
||||
className={className}
|
||||
responsive={false}
|
||||
>
|
||||
{renderItems()}
|
||||
</EuiFlexGroup>
|
||||
{renderMenu(className)}
|
||||
{renderSearchBar()}
|
||||
</span>
|
||||
);
|
||||
|
|
|
@ -44,7 +44,9 @@ exports[`share url panel content render 1`] = `
|
|||
gutterSize="none"
|
||||
responsive={false}
|
||||
>
|
||||
<EuiFlexItem>
|
||||
<EuiFlexItem
|
||||
grow={false}
|
||||
>
|
||||
<FormattedMessage
|
||||
defaultMessage="Snapshot"
|
||||
id="share.urlPanel.snapshotLabel"
|
||||
|
@ -79,7 +81,9 @@ exports[`share url panel content render 1`] = `
|
|||
gutterSize="none"
|
||||
responsive={false}
|
||||
>
|
||||
<EuiFlexItem>
|
||||
<EuiFlexItem
|
||||
grow={false}
|
||||
>
|
||||
<FormattedMessage
|
||||
defaultMessage="Saved object"
|
||||
id="share.urlPanel.savedObjectLabel"
|
||||
|
@ -123,7 +127,9 @@ exports[`share url panel content render 1`] = `
|
|||
gutterSize="none"
|
||||
responsive={false}
|
||||
>
|
||||
<EuiFlexItem>
|
||||
<EuiFlexItem
|
||||
grow={false}
|
||||
>
|
||||
<EuiSwitch
|
||||
checked={false}
|
||||
data-test-subj="useShortUrl"
|
||||
|
@ -200,7 +206,9 @@ exports[`share url panel content should enable saved object export option when o
|
|||
gutterSize="none"
|
||||
responsive={false}
|
||||
>
|
||||
<EuiFlexItem>
|
||||
<EuiFlexItem
|
||||
grow={false}
|
||||
>
|
||||
<FormattedMessage
|
||||
defaultMessage="Snapshot"
|
||||
id="share.urlPanel.snapshotLabel"
|
||||
|
@ -235,7 +243,9 @@ exports[`share url panel content should enable saved object export option when o
|
|||
gutterSize="none"
|
||||
responsive={false}
|
||||
>
|
||||
<EuiFlexItem>
|
||||
<EuiFlexItem
|
||||
grow={false}
|
||||
>
|
||||
<FormattedMessage
|
||||
defaultMessage="Saved object"
|
||||
id="share.urlPanel.savedObjectLabel"
|
||||
|
@ -279,7 +289,9 @@ exports[`share url panel content should enable saved object export option when o
|
|||
gutterSize="none"
|
||||
responsive={false}
|
||||
>
|
||||
<EuiFlexItem>
|
||||
<EuiFlexItem
|
||||
grow={false}
|
||||
>
|
||||
<EuiSwitch
|
||||
checked={false}
|
||||
data-test-subj="useShortUrl"
|
||||
|
@ -356,7 +368,9 @@ exports[`share url panel content should hide short url section when allowShortUr
|
|||
gutterSize="none"
|
||||
responsive={false}
|
||||
>
|
||||
<EuiFlexItem>
|
||||
<EuiFlexItem
|
||||
grow={false}
|
||||
>
|
||||
<FormattedMessage
|
||||
defaultMessage="Snapshot"
|
||||
id="share.urlPanel.snapshotLabel"
|
||||
|
@ -391,7 +405,9 @@ exports[`share url panel content should hide short url section when allowShortUr
|
|||
gutterSize="none"
|
||||
responsive={false}
|
||||
>
|
||||
<EuiFlexItem>
|
||||
<EuiFlexItem
|
||||
grow={false}
|
||||
>
|
||||
<FormattedMessage
|
||||
defaultMessage="Saved object"
|
||||
id="share.urlPanel.savedObjectLabel"
|
||||
|
@ -435,3 +451,178 @@ exports[`share url panel content should hide short url section when allowShortUr
|
|||
</EuiForm>
|
||||
</I18nProvider>
|
||||
`;
|
||||
|
||||
exports[`should show url param extensions 1`] = `
|
||||
<I18nProvider>
|
||||
<EuiForm
|
||||
className="kbnShareContextMenu__finalPanel"
|
||||
data-test-subj="shareUrlForm"
|
||||
>
|
||||
<EuiFormRow
|
||||
describedByIds={Array []}
|
||||
display="row"
|
||||
fullWidth={false}
|
||||
hasChildLabel={true}
|
||||
hasEmptyLabelSpace={false}
|
||||
label={
|
||||
<FormattedMessage
|
||||
defaultMessage="Generate the link as"
|
||||
id="share.urlPanel.generateLinkAsLabel"
|
||||
values={Object {}}
|
||||
/>
|
||||
}
|
||||
labelType="label"
|
||||
>
|
||||
<EuiRadioGroup
|
||||
idSelected="snapshot"
|
||||
onChange={[Function]}
|
||||
options={
|
||||
Array [
|
||||
Object {
|
||||
"data-test-subj": "exportAsSnapshot",
|
||||
"id": "snapshot",
|
||||
"label": <ForwardRef
|
||||
gutterSize="none"
|
||||
responsive={false}
|
||||
>
|
||||
<EuiFlexItem
|
||||
grow={false}
|
||||
>
|
||||
<FormattedMessage
|
||||
defaultMessage="Snapshot"
|
||||
id="share.urlPanel.snapshotLabel"
|
||||
values={Object {}}
|
||||
/>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem
|
||||
grow={false}
|
||||
>
|
||||
<EuiIconTip
|
||||
content={
|
||||
<FormattedMessage
|
||||
defaultMessage="Snapshot URLs encode the current state of the {objectType} in the URL itself. Edits to the saved {objectType} won't be visible via this URL."
|
||||
id="share.urlPanel.snapshotDescription"
|
||||
values={
|
||||
Object {
|
||||
"objectType": "dashboard",
|
||||
}
|
||||
}
|
||||
/>
|
||||
}
|
||||
position="bottom"
|
||||
/>
|
||||
</EuiFlexItem>
|
||||
</ForwardRef>,
|
||||
},
|
||||
Object {
|
||||
"data-test-subj": "exportAsSavedObject",
|
||||
"disabled": false,
|
||||
"id": "savedObject",
|
||||
"label": <ForwardRef
|
||||
gutterSize="none"
|
||||
responsive={false}
|
||||
>
|
||||
<EuiFlexItem
|
||||
grow={false}
|
||||
>
|
||||
<FormattedMessage
|
||||
defaultMessage="Saved object"
|
||||
id="share.urlPanel.savedObjectLabel"
|
||||
values={Object {}}
|
||||
/>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem
|
||||
grow={false}
|
||||
>
|
||||
<EuiIconTip
|
||||
content={
|
||||
<FormattedMessage
|
||||
defaultMessage="You can share this URL with people to let them load the most recent saved version of this {objectType}."
|
||||
id="share.urlPanel.savedObjectDescription"
|
||||
values={
|
||||
Object {
|
||||
"objectType": "dashboard",
|
||||
}
|
||||
}
|
||||
/>
|
||||
}
|
||||
position="bottom"
|
||||
/>
|
||||
</EuiFlexItem>
|
||||
</ForwardRef>,
|
||||
},
|
||||
]
|
||||
}
|
||||
/>
|
||||
</EuiFormRow>
|
||||
<EuiFormRow
|
||||
describedByIds={Array []}
|
||||
display="row"
|
||||
fullWidth={false}
|
||||
hasChildLabel={true}
|
||||
hasEmptyLabelSpace={false}
|
||||
key="testExtension"
|
||||
labelType="label"
|
||||
>
|
||||
<TestExtension
|
||||
setParamValue={[Function]}
|
||||
/>
|
||||
</EuiFormRow>
|
||||
<EuiFormRow
|
||||
data-test-subj="createShortUrl"
|
||||
describedByIds={Array []}
|
||||
display="row"
|
||||
fullWidth={false}
|
||||
hasChildLabel={true}
|
||||
hasEmptyLabelSpace={false}
|
||||
labelType="label"
|
||||
>
|
||||
<EuiFlexGroup
|
||||
gutterSize="none"
|
||||
responsive={false}
|
||||
>
|
||||
<EuiFlexItem
|
||||
grow={false}
|
||||
>
|
||||
<EuiSwitch
|
||||
checked={false}
|
||||
data-test-subj="useShortUrl"
|
||||
label={
|
||||
<FormattedMessage
|
||||
defaultMessage="Short URL"
|
||||
id="share.urlPanel.shortUrlLabel"
|
||||
values={Object {}}
|
||||
/>
|
||||
}
|
||||
onChange={[Function]}
|
||||
/>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem
|
||||
grow={false}
|
||||
>
|
||||
<EuiIconTip
|
||||
content={
|
||||
<FormattedMessage
|
||||
defaultMessage="We recommend sharing shortened snapshot URLs for maximum compatibility. Internet Explorer has URL length restrictions, and some wiki and markup parsers don't do well with the full-length version of the snapshot URL, but the short URL should work great."
|
||||
id="share.urlPanel.shortUrlHelpText"
|
||||
values={Object {}}
|
||||
/>
|
||||
}
|
||||
position="bottom"
|
||||
/>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
</EuiFormRow>
|
||||
<EuiSpacer
|
||||
size="m"
|
||||
/>
|
||||
<EuiCopy
|
||||
afterMessage="Copied"
|
||||
anchorClassName="eui-displayBlock"
|
||||
textToCopy="http://localhost/"
|
||||
>
|
||||
<Component />
|
||||
</EuiCopy>
|
||||
</EuiForm>
|
||||
</I18nProvider>
|
||||
`;
|
||||
|
|
|
@ -26,7 +26,7 @@ import { EuiContextMenu, EuiContextMenuPanelDescriptor } from '@elastic/eui';
|
|||
import { HttpStart } from 'kibana/public';
|
||||
|
||||
import { UrlPanelContent } from './url_panel_content';
|
||||
import { ShareMenuItem, ShareContextMenuPanelItem } from '../types';
|
||||
import { ShareMenuItem, ShareContextMenuPanelItem, UrlParamExtension } from '../types';
|
||||
|
||||
interface Props {
|
||||
allowEmbed: boolean;
|
||||
|
@ -39,6 +39,7 @@ interface Props {
|
|||
onClose: () => void;
|
||||
basePath: string;
|
||||
post: HttpStart['post'];
|
||||
embedUrlParamExtensions?: UrlParamExtension[];
|
||||
}
|
||||
|
||||
export class ShareContextMenu extends Component<Props> {
|
||||
|
@ -100,6 +101,7 @@ export class ShareContextMenu extends Component<Props> {
|
|||
basePath={this.props.basePath}
|
||||
post={this.props.post}
|
||||
shareableUrl={this.props.shareableUrl}
|
||||
urlParamExtensions={this.props.embedUrlParamExtensions}
|
||||
/>
|
||||
),
|
||||
};
|
||||
|
|
|
@ -202,3 +202,13 @@ describe('share url panel content', () => {
|
|||
});
|
||||
});
|
||||
});
|
||||
|
||||
test('should show url param extensions', () => {
|
||||
const TestExtension = () => <div data-test-subj="testExtension" />;
|
||||
const extensions = [{ paramName: 'testExtension', component: TestExtension }];
|
||||
const component = shallow(
|
||||
<UrlPanelContent {...defaultProps} urlParamExtensions={extensions} objectId="id1" />
|
||||
);
|
||||
expect(component.find('TestExtension').length).toBe(1);
|
||||
expect(component).toMatchSnapshot();
|
||||
});
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
* under the License.
|
||||
*/
|
||||
|
||||
import React, { Component } from 'react';
|
||||
import React, { Component, ReactElement } from 'react';
|
||||
|
||||
import {
|
||||
EuiButton,
|
||||
|
@ -41,6 +41,7 @@ import { HttpStart } from 'kibana/public';
|
|||
import { i18n } from '@kbn/i18n';
|
||||
|
||||
import { shortenUrl } from '../lib/url_shortener';
|
||||
import { UrlParamExtension } from '../types';
|
||||
|
||||
interface Props {
|
||||
allowShortUrl: boolean;
|
||||
|
@ -50,6 +51,7 @@ interface Props {
|
|||
shareableUrl?: string;
|
||||
basePath: string;
|
||||
post: HttpStart['post'];
|
||||
urlParamExtensions?: UrlParamExtension[];
|
||||
}
|
||||
|
||||
export enum ExportUrlAsType {
|
||||
|
@ -57,12 +59,19 @@ export enum ExportUrlAsType {
|
|||
EXPORT_URL_AS_SNAPSHOT = 'snapshot',
|
||||
}
|
||||
|
||||
interface UrlParams {
|
||||
[extensionName: string]: {
|
||||
[queryParam: string]: boolean;
|
||||
};
|
||||
}
|
||||
|
||||
interface State {
|
||||
exportUrlAs: ExportUrlAsType;
|
||||
useShortUrl: boolean;
|
||||
isCreatingShortUrl: boolean;
|
||||
url?: string;
|
||||
shortUrlErrorMsg?: string;
|
||||
urlParams?: UrlParams;
|
||||
}
|
||||
|
||||
export class UrlPanelContent extends Component<Props, State> {
|
||||
|
@ -100,7 +109,7 @@ export class UrlPanelContent extends Component<Props, State> {
|
|||
<I18nProvider>
|
||||
<EuiForm className="kbnShareContextMenu__finalPanel" data-test-subj="shareUrlForm">
|
||||
{this.renderExportAsRadioGroup()}
|
||||
|
||||
{this.renderUrlParamExtensions()}
|
||||
{this.renderShortUrlSwitch()}
|
||||
|
||||
<EuiSpacer size="m" />
|
||||
|
@ -151,6 +160,13 @@ export class UrlPanelContent extends Component<Props, State> {
|
|||
}
|
||||
};
|
||||
|
||||
private updateUrlParams = (url: string) => {
|
||||
const embedUrl = this.props.isEmbedded ? this.makeUrlEmbeddable(url) : url;
|
||||
const extendUrl = this.state.urlParams ? this.getUrlParamExtensions(embedUrl) : embedUrl;
|
||||
|
||||
return extendUrl;
|
||||
};
|
||||
|
||||
private getSavedObjectUrl = () => {
|
||||
if (this.isNotSaved()) {
|
||||
return;
|
||||
|
@ -166,7 +182,7 @@ export class UrlPanelContent extends Component<Props, State> {
|
|||
// Get the application route, after the hash, and remove the #.
|
||||
const parsedAppUrl = parseUrl(parsedUrl.hash.slice(1), true);
|
||||
|
||||
let formattedUrl = formatUrl({
|
||||
const formattedUrl = formatUrl({
|
||||
protocol: parsedUrl.protocol,
|
||||
auth: parsedUrl.auth,
|
||||
host: parsedUrl.host,
|
||||
|
@ -180,28 +196,42 @@ export class UrlPanelContent extends Component<Props, State> {
|
|||
},
|
||||
}),
|
||||
});
|
||||
if (this.props.isEmbedded) {
|
||||
formattedUrl = this.makeUrlEmbeddable(formattedUrl);
|
||||
}
|
||||
|
||||
return formattedUrl;
|
||||
return this.updateUrlParams(formattedUrl);
|
||||
};
|
||||
|
||||
private getSnapshotUrl = () => {
|
||||
let url = this.props.shareableUrl || window.location.href;
|
||||
if (this.props.isEmbedded) {
|
||||
url = this.makeUrlEmbeddable(url);
|
||||
}
|
||||
return url;
|
||||
const url = this.props.shareableUrl || window.location.href;
|
||||
|
||||
return this.updateUrlParams(url);
|
||||
};
|
||||
|
||||
private makeUrlEmbeddable = (url: string) => {
|
||||
const embedQueryParam = '?embed=true';
|
||||
private makeUrlEmbeddable = (url: string): string => {
|
||||
const embedParam = '?embed=true';
|
||||
const urlHasQueryString = url.indexOf('?') !== -1;
|
||||
|
||||
if (urlHasQueryString) {
|
||||
return url.replace('?', `${embedQueryParam}&`);
|
||||
return url.replace('?', `${embedParam}&`);
|
||||
}
|
||||
return `${url}${embedQueryParam}`;
|
||||
|
||||
return `${url}${embedParam}`;
|
||||
};
|
||||
|
||||
private getUrlParamExtensions = (url: string): string => {
|
||||
const { urlParams } = this.state;
|
||||
return urlParams
|
||||
? Object.keys(urlParams).reduce((urlAccumulator, key) => {
|
||||
const urlParam = urlParams[key];
|
||||
return urlParam
|
||||
? Object.keys(urlParam).reduce((queryAccumulator, queryParam) => {
|
||||
const isQueryParamEnabled = urlParam[queryParam];
|
||||
return isQueryParamEnabled
|
||||
? queryAccumulator + `&${queryParam}=true`
|
||||
: queryAccumulator;
|
||||
}, urlAccumulator)
|
||||
: urlAccumulator;
|
||||
}, url)
|
||||
: url;
|
||||
};
|
||||
|
||||
private makeIframeTag = (url?: string) => {
|
||||
|
@ -247,6 +277,10 @@ export class UrlPanelContent extends Component<Props, State> {
|
|||
}
|
||||
|
||||
// "Use short URL" is checked but shortUrl has not been generated yet so one needs to be created.
|
||||
this.createShortUrl();
|
||||
};
|
||||
|
||||
private createShortUrl = async () => {
|
||||
this.setState({
|
||||
isCreatingShortUrl: true,
|
||||
shortUrlErrorMsg: undefined,
|
||||
|
@ -262,7 +296,7 @@ export class UrlPanelContent extends Component<Props, State> {
|
|||
this.setState(
|
||||
{
|
||||
isCreatingShortUrl: false,
|
||||
useShortUrl: isChecked,
|
||||
useShortUrl: true,
|
||||
},
|
||||
this.setUrl
|
||||
);
|
||||
|
@ -321,7 +355,7 @@ export class UrlPanelContent extends Component<Props, State> {
|
|||
private renderWithIconTip = (child: React.ReactNode, tipContent: React.ReactNode) => {
|
||||
return (
|
||||
<EuiFlexGroup gutterSize="none" responsive={false}>
|
||||
<EuiFlexItem>{child}</EuiFlexItem>
|
||||
<EuiFlexItem grow={false}>{child}</EuiFlexItem>
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiIconTip content={tipContent} position="bottom" />
|
||||
</EuiFlexItem>
|
||||
|
@ -397,4 +431,34 @@ export class UrlPanelContent extends Component<Props, State> {
|
|||
</EuiFormRow>
|
||||
);
|
||||
};
|
||||
|
||||
private renderUrlParamExtensions = (): ReactElement | void => {
|
||||
if (!this.props.urlParamExtensions) {
|
||||
return;
|
||||
}
|
||||
|
||||
const setParamValue = (paramName: string) => (
|
||||
values: { [queryParam: string]: boolean } = {}
|
||||
): void => {
|
||||
const stateUpdate = {
|
||||
urlParams: {
|
||||
...this.state.urlParams,
|
||||
[paramName]: {
|
||||
...values,
|
||||
},
|
||||
},
|
||||
};
|
||||
this.setState(stateUpdate, this.state.useShortUrl ? this.createShortUrl : this.setUrl);
|
||||
};
|
||||
|
||||
return (
|
||||
<React.Fragment>
|
||||
{this.props.urlParamExtensions.map(({ paramName, component: UrlParamComponent }) => (
|
||||
<EuiFormRow key={paramName}>
|
||||
<UrlParamComponent setParamValue={setParamValue(paramName)} />
|
||||
</EuiFormRow>
|
||||
))}
|
||||
</React.Fragment>
|
||||
);
|
||||
};
|
||||
}
|
||||
|
|
|
@ -67,6 +67,7 @@ export class ShareMenuManager {
|
|||
shareableUrl,
|
||||
post,
|
||||
basePath,
|
||||
embedUrlParamExtensions,
|
||||
}: ShowShareMenuOptions & {
|
||||
menuItems: ShareMenuItem[];
|
||||
post: HttpStart['post'];
|
||||
|
@ -102,6 +103,7 @@ export class ShareMenuManager {
|
|||
onClose={this.onClose}
|
||||
post={post}
|
||||
basePath={basePath}
|
||||
embedUrlParamExtensions={embedUrlParamExtensions}
|
||||
/>
|
||||
</EuiWrappingPopover>
|
||||
</I18nProvider>
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
* under the License.
|
||||
*/
|
||||
|
||||
import { ComponentType } from 'react';
|
||||
import { EuiContextMenuPanelDescriptor, EuiContextMenuPanelItemDescriptor } from '@elastic/eui';
|
||||
|
||||
/**
|
||||
|
@ -80,9 +81,19 @@ export interface ShareMenuProvider {
|
|||
getShareMenuItems: (context: ShareContext) => ShareMenuItem[];
|
||||
}
|
||||
|
||||
interface UrlParamExtensionProps {
|
||||
setParamValue: (values: {}) => void;
|
||||
}
|
||||
|
||||
export interface UrlParamExtension {
|
||||
paramName: string;
|
||||
component: ComponentType<UrlParamExtensionProps>;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export interface ShowShareMenuOptions extends Omit<ShareContext, 'onClose'> {
|
||||
anchorElement: HTMLElement;
|
||||
allowEmbed: boolean;
|
||||
allowShortUrl: boolean;
|
||||
embedUrlParamExtensions?: UrlParamExtension[];
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
import expect from '@kbn/expect';
|
||||
|
||||
export default function ({ getService, getPageObjects }) {
|
||||
const testSubjects = getService('testSubjects');
|
||||
const retry = getService('retry');
|
||||
const esArchiver = getService('esArchiver');
|
||||
const kibanaServer = getService('kibanaServer');
|
||||
|
@ -28,6 +29,13 @@ export default function ({ getService, getPageObjects }) {
|
|||
const globalNav = getService('globalNav');
|
||||
|
||||
describe('embed mode', () => {
|
||||
const urlParamExtensions = [
|
||||
'show-top-menu=true',
|
||||
'show-query-input=true',
|
||||
'show-time-filter=true',
|
||||
'hide-filter-bar=true',
|
||||
];
|
||||
|
||||
before(async () => {
|
||||
await esArchiver.load('dashboard/current/kibana');
|
||||
await kibanaServer.uiSettings.replace({
|
||||
|
@ -54,9 +62,28 @@ export default function ({ getService, getPageObjects }) {
|
|||
});
|
||||
});
|
||||
|
||||
it('shows or hides elements based on URL params', async () => {
|
||||
await testSubjects.missingOrFail('top-nav');
|
||||
await testSubjects.missingOrFail('queryInput');
|
||||
await testSubjects.missingOrFail('superDatePickerToggleQuickMenuButton');
|
||||
await testSubjects.existOrFail('showFilterActions');
|
||||
|
||||
const currentUrl = await browser.getCurrentUrl();
|
||||
const newUrl = [currentUrl].concat(urlParamExtensions).join('&');
|
||||
// Embed parameter only works on a hard refresh.
|
||||
const useTimeStamp = true;
|
||||
await browser.get(newUrl.toString(), useTimeStamp);
|
||||
|
||||
await testSubjects.existOrFail('top-nav');
|
||||
await testSubjects.existOrFail('queryInput');
|
||||
await testSubjects.existOrFail('superDatePickerToggleQuickMenuButton');
|
||||
await testSubjects.missingOrFail('showFilterActions');
|
||||
});
|
||||
|
||||
after(async function () {
|
||||
const currentUrl = await browser.getCurrentUrl();
|
||||
const newUrl = currentUrl.replace('&embed=true', '');
|
||||
const replaceParams = ['', 'embed=true'].concat(urlParamExtensions).join('&');
|
||||
const newUrl = currentUrl.replace(replaceParams, '');
|
||||
// First use the timestamp to cause a hard refresh so the new embed parameter works correctly.
|
||||
let useTimeStamp = true;
|
||||
await browser.get(newUrl.toString(), useTimeStamp);
|
||||
|
|
|
@ -92,6 +92,7 @@ export const dashboardInput: DashboardContainerInput = {
|
|||
},
|
||||
},
|
||||
},
|
||||
isEmbeddedExternally: false,
|
||||
isFullScreenMode: false,
|
||||
filters: [],
|
||||
useMargins: true,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue