typescript more dashboard panel code (#21810)

* typescript more dashboard panel code

* use ? instead of | undefined
This commit is contained in:
Stacey Gammon 2018-08-12 06:53:13 -04:00 committed by GitHub
parent 222dd91823
commit 62f35df89b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
22 changed files with 298 additions and 147 deletions

View file

@ -241,6 +241,7 @@
"@types/prop-types": "^15.5.3",
"@types/react": "^16.3.14",
"@types/react-dom": "^16.0.5",
"@types/react-redux": "^5.0.6",
"@types/redux": "^3.6.31",
"@types/redux-actions": "^2.2.1",
"@types/sinon": "^5.0.0",

View file

@ -44,7 +44,7 @@ export interface ResetPanelTitleAction
export interface SetPanelTitleActionPayload {
panelId: PanelId;
title: string;
title?: string;
}
export interface SetPanelTitleAction

View file

@ -34,6 +34,7 @@ export enum ViewActionTypeKeys {
UPDATE_TIME_RANGE = 'UPDATE_TIME_RANGE',
UPDATE_FILTERS = 'UPDATE_FILTERS',
UPDATE_QUERY = 'UPDATE_QUERY',
CLOSE_CONTEXT_MENU = 'CLOSE_CONTEXT_MENU',
}
export interface UpdateViewModeAction
@ -42,6 +43,9 @@ export interface UpdateViewModeAction
export interface SetVisibleContextMenuPanelIdAction
extends KibanaAction<ViewActionTypeKeys.SET_VISIBLE_CONTEXT_MENU_PANEL_ID, PanelId> {}
export interface CloseContextMenuAction
extends KibanaAction<ViewActionTypeKeys.CLOSE_CONTEXT_MENU, undefined> {}
export interface MaximizePanelAction
extends KibanaAction<ViewActionTypeKeys.MAXIMIZE_PANEl, PanelId> {}
@ -68,6 +72,7 @@ export interface UpdateQueryAction extends KibanaAction<ViewActionTypeKeys.UPDAT
export type ViewActions =
| UpdateViewModeAction
| SetVisibleContextMenuPanelIdAction
| CloseContextMenuAction
| MaximizePanelAction
| MinimizePanelAction
| UpdateIsFullScreenModeAction
@ -78,6 +83,7 @@ export type ViewActions =
| UpdateQueryAction;
export const updateViewMode = createAction<string>(ViewActionTypeKeys.UPDATE_VIEW_MODE);
export const closeContextMenu = createAction(ViewActionTypeKeys.CLOSE_CONTEXT_MENU);
export const setVisibleContextMenuPanelId = createAction<PanelId>(
ViewActionTypeKeys.SET_VISIBLE_CONTEXT_MENU_PANEL_ID
);

View file

@ -17,14 +17,18 @@
* under the License.
*/
import { EuiContextMenuPanelDescriptor, EuiContextMenuPanelItemDescriptor } from '@elastic/eui';
import _ from 'lodash';
import { DashboardContextMenuPanel, DashboardPanelAction } from 'ui/dashboard_panel_actions';
import { ContainerState, Embeddable } from 'ui/embeddable';
import { PanelId } from '../../../selectors';
/**
* Loops through allActions and extracts those that belong on the given contextMenuPanelId
* @param {string} contextMenuPanelId
* @param {Array.<DashboardPanelAction>} allActions
*/
function getActionsForPanel(contextMenuPanelId, allActions) {
function getActionsForPanel(contextMenuPanelId: PanelId, allActions: DashboardPanelAction[]) {
return allActions.filter(action => action.parentPanelId === contextMenuPanelId);
}
@ -34,15 +38,25 @@ function getActionsForPanel(contextMenuPanelId, allActions) {
* @param {Embeddable} embeddable
* @param {ContainerState} containerState
* @return {{
* Array.<EuiContextMenuPanelItemShape> items - panel actions converted into the items expected to be on an
* Array.<EuiContextMenuPanelItemDescriptor> items - panel actions converted into the items expected to be on an
* EuiContextMenuPanel,
* Array.<EuiContextMenuPanelShape> childPanels - extracted child panels, if any actions also open a panel. They
* Array.<EuiContextMenuPanelDescriptor> childPanels - extracted child panels, if any actions also open a panel. They
* need to be moved to the top level for EUI.
* }}
*/
function buildEuiContextMenuPanelItemsAndChildPanels({ contextMenuPanelId, actions, embeddable, containerState }) {
const items = [];
const childPanels = [];
function buildEuiContextMenuPanelItemsAndChildPanels({
contextMenuPanelId,
actions,
embeddable,
containerState,
}: {
contextMenuPanelId: PanelId;
actions: DashboardPanelAction[];
embeddable?: Embeddable;
containerState: ContainerState;
}) {
const items: EuiContextMenuPanelItemDescriptor[] = [];
const childPanels: EuiContextMenuPanelDescriptor[] = [];
const actionsForPanel = getActionsForPanel(contextMenuPanelId, actions);
actionsForPanel.forEach(action => {
const isVisible = action.isVisible({ embeddable, containerState });
@ -56,16 +70,18 @@ function buildEuiContextMenuPanelItemsAndChildPanels({ contextMenuPanelId, actio
contextMenuPanel: action.childContextMenuPanel,
actions,
embeddable,
containerState
}));
containerState,
})
);
}
items.push(convertPanelActionToContextMenuItem(
{
items.push(
convertPanelActionToContextMenuItem({
action,
containerState,
embeddable
}));
embeddable,
})
);
});
return { items, childPanels };
@ -78,16 +94,20 @@ function buildEuiContextMenuPanelItemsAndChildPanels({ contextMenuPanelId, actio
* @param {Array.<DashboardPanelAction>} actions to build the context menu with
* @param {Embeddable} embeddable
* @param {ContainerState} containerState
* @return {Object} An object that conforms to EuiContextMenuPanelShape in elastic/eui
* @return {EuiContextMenuPanelDescriptor[]} An array of context menu panels to be used in the eui react component.
*/
export function buildEuiContextMenuPanels(
{
contextMenuPanel,
actions,
embeddable,
containerState
}) {
const euiContextMenuPanel = {
export function buildEuiContextMenuPanels({
contextMenuPanel,
actions,
embeddable,
containerState,
}: {
contextMenuPanel: DashboardContextMenuPanel;
actions: DashboardPanelAction[];
embeddable?: Embeddable;
containerState: ContainerState;
}): EuiContextMenuPanelDescriptor[] {
const euiContextMenuPanel: EuiContextMenuPanelDescriptor = {
id: contextMenuPanel.id,
title: contextMenuPanel.title,
items: [],
@ -95,13 +115,12 @@ export function buildEuiContextMenuPanels(
};
const contextMenuPanels = [euiContextMenuPanel];
const { items, childPanels } =
buildEuiContextMenuPanelItemsAndChildPanels({
contextMenuPanelId: contextMenuPanel.id,
actions,
embeddable,
containerState
});
const { items, childPanels } = buildEuiContextMenuPanelItemsAndChildPanels({
contextMenuPanelId: contextMenuPanel.id,
actions,
embeddable,
containerState,
});
euiContextMenuPanel.items = items;
return contextMenuPanels.concat(childPanels);
@ -112,11 +131,18 @@ export function buildEuiContextMenuPanels(
* @param {DashboardPanelAction} action
* @param {ContainerState} containerState
* @param {Embeddable} embeddable
* @return {Object} See EuiContextMenuPanelItemShape in @elastic/eui
* @return {EuiContextMenuPanelItemDescriptor}
*/
function convertPanelActionToContextMenuItem({ action, containerState, embeddable }) {
function convertPanelActionToContextMenuItem({
action,
containerState,
embeddable,
}: {
action: DashboardPanelAction;
containerState: ContainerState;
embeddable?: Embeddable;
}): EuiContextMenuPanelItemDescriptor {
return {
id: action.id || action.displayName.replace(/\s/g, ''),
name: action.displayName,
icon: action.icon,
panel: _.get(action, 'childContextMenuPanel.id'),
@ -125,4 +151,3 @@ function convertPanelActionToContextMenuItem({ action, containerState, embeddabl
'data-test-subj': `dashboardPanelAction-${action.id}`,
};
}

View file

@ -30,7 +30,7 @@ export function getCustomizePanelAction({
title,
}: {
onResetPanelTitle: () => void;
onUpdatePanelTitle: (title: string | undefined) => void;
onUpdatePanelTitle: (title: string) => void;
closeContextMenu: () => void;
title?: string;
}): DashboardPanelAction {

View file

@ -41,7 +41,7 @@ export function getEditPanelAction() {
!embeddable || !embeddable.metadata || !embeddable.metadata.editUrl,
isVisible: ({ containerState }) => containerState.viewMode === DashboardViewMode.EDIT,
onClick: ({ embeddable }) => {
if (embeddable.metadata.editUrl) {
if (embeddable && embeddable.metadata.editUrl) {
window.location.href = embeddable.metadata.editUrl;
}
},

View file

@ -46,9 +46,16 @@ export function getInspectorPanelAction({
},
{
icon: <EuiIcon type="inspect" />,
isVisible: ({ embeddable }) =>
embeddable && Inspector.isAvailable(embeddable.getInspectorAdapters()),
isVisible: ({ embeddable }) => {
if (!embeddable) {
return false;
}
return Inspector.isAvailable(embeddable.getInspectorAdapters());
},
onClick: ({ embeddable }) => {
if (!embeddable) {
return;
}
closeContextMenu();
const adapters = embeddable.getInspectorAdapters();
if (!adapters) {

View file

@ -18,11 +18,25 @@
*/
import React from 'react';
import PropTypes from 'prop-types';
import { embeddableShape } from 'ui/embeddable';
import { Embeddable } from 'ui/embeddable';
import { PanelId } from '../../selectors';
import { PanelOptionsMenuContainer } from './panel_options_menu_container';
export function PanelHeader({ title, panelId, embeddable, isViewOnlyMode, hidePanelTitles }) {
export interface PanelHeaderProps {
title?: string;
panelId: PanelId;
embeddable?: Embeddable;
isViewOnlyMode: boolean;
hidePanelTitles: boolean;
}
export function PanelHeader({
title,
panelId,
embeddable,
isViewOnlyMode,
hidePanelTitles,
}: PanelHeaderProps) {
if (isViewOnlyMode && (!title || hidePanelTitles)) {
return (
<div className="panel-heading-floater">
@ -34,7 +48,10 @@ export function PanelHeader({ title, panelId, embeddable, isViewOnlyMode, hidePa
}
return (
<div className="panel-heading" data-test-subj={`dashboardPanelHeading-${title.replace(/\s/g, '')}`}>
<div
className="panel-heading"
data-test-subj={`dashboardPanelHeading-${(title || '').replace(/\s/g, '')}`}
>
<span
data-test-subj="dashboardPanelTitle"
className="panel-title"
@ -50,11 +67,3 @@ export function PanelHeader({ title, panelId, embeddable, isViewOnlyMode, hidePa
</div>
);
}
PanelHeader.propTypes = {
isViewOnlyMode: PropTypes.bool,
title: PropTypes.string,
hidePanelTitles: PropTypes.bool.isRequired,
embeddable: embeddableShape,
panelId: PropTypes.string.isRequired,
};

View file

@ -17,37 +17,57 @@
* under the License.
*/
import { mount, ReactWrapper } from 'enzyme';
import _ from 'lodash';
import React from 'react';
import { Provider } from 'react-redux';
import _ from 'lodash';
import { mount } from 'enzyme';
import { PanelHeaderContainer } from './panel_header_container';
import { DashboardViewMode } from '../../dashboard_view_mode';
import { store } from '../../../store';
import {
updateViewMode,
setPanels,
setPanelTitle,
resetPanelTitle,
embeddableIsInitialized,
updateTimeRange,
} from '../../actions';
// TODO: remove this when EUI supports types for this.
// @ts-ignore: implicit any for JS file
import { findTestSubject } from '@elastic/eui/lib/test';
function getProps(props = {}) {
import { store } from '../../../store';
import {
embeddableIsInitialized,
resetPanelTitle,
setPanels,
setPanelTitle,
updateTimeRange,
updateViewMode,
} from '../../actions';
import { DashboardViewMode } from '../../dashboard_view_mode';
import { PanelHeaderContainer, PanelHeaderContainerOwnProps } from './panel_header_container';
function getProps(props = {}): PanelHeaderContainerOwnProps {
const defaultTestProps = {
panelId: 'foo1',
};
return _.defaultsDeep(props, defaultTestProps);
}
let component;
let component: ReactWrapper;
beforeAll(() => {
store.dispatch(updateTimeRange({ to: 'now', from: 'now-15m' }));
store.dispatch(updateViewMode(DashboardViewMode.EDIT));
store.dispatch(setPanels({ 'foo1': { panelIndex: 'foo1' } }));
store.dispatch(
setPanels({
foo1: {
panelIndex: 'foo1',
id: 'hi',
version: '123',
type: 'viz',
embeddableConfig: {},
gridData: {
x: 1,
y: 1,
w: 1,
h: 1,
id: 'hi',
},
},
})
);
const metadata = { title: 'my embeddable title', editUrl: 'editme' };
store.dispatch(embeddableIsInitialized({ metadata, panelId: 'foo1' }));
});
@ -57,7 +77,11 @@ afterAll(() => {
});
test('Panel header shows embeddable title when nothing is set on the panel', () => {
component = mount(<Provider store={store}><PanelHeaderContainer {...getProps()} /></Provider>);
component = mount(
<Provider store={store}>
<PanelHeaderContainer {...getProps()} />
</Provider>
);
expect(findTestSubject(component, 'dashboardPanelTitle').text()).toBe('my embeddable title');
});

View file

@ -17,38 +17,53 @@
* under the License.
*/
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import { embeddableShape } from 'ui/embeddable';
import { PanelHeader } from './panel_header';
import { Embeddable } from 'ui/embeddable';
import { DashboardViewMode } from '../../dashboard_view_mode';
import { PanelHeader } from './panel_header';
import { CoreKibanaState } from '../../../selectors';
import {
getPanel,
getMaximizedPanelId,
getEmbeddableTitle,
getFullScreenMode,
getViewMode,
getHidePanelTitles,
getEmbeddableTitle
getMaximizedPanelId,
getPanel,
getViewMode,
PanelId,
} from '../../selectors';
const mapStateToProps = ({ dashboard }, { panelId }) => {
export interface PanelHeaderContainerOwnProps {
panelId: PanelId;
embeddable?: Embeddable;
}
interface PanelHeaderContainerStateProps {
title?: string;
isExpanded: boolean;
isViewOnlyMode: boolean;
hidePanelTitles: boolean;
}
const mapStateToProps = (
{ dashboard }: CoreKibanaState,
{ panelId }: PanelHeaderContainerOwnProps
) => {
const panel = getPanel(dashboard, panelId);
const embeddableTitle = getEmbeddableTitle(dashboard, panelId);
return {
title: panel.title === undefined ? embeddableTitle : panel.title,
isExpanded: getMaximizedPanelId(dashboard) === panelId,
isViewOnlyMode: getFullScreenMode(dashboard) || getViewMode(dashboard) === DashboardViewMode.VIEW,
isViewOnlyMode:
getFullScreenMode(dashboard) || getViewMode(dashboard) === DashboardViewMode.VIEW,
hidePanelTitles: getHidePanelTitles(dashboard),
};
};
export const PanelHeaderContainer = connect(
mapStateToProps,
)(PanelHeader);
PanelHeaderContainer.propTypes = {
panelId: PropTypes.string.isRequired,
embeddable: embeddableShape,
};
export const PanelHeaderContainer = connect<
PanelHeaderContainerStateProps,
{},
PanelHeaderContainerOwnProps,
CoreKibanaState
>(mapStateToProps)(PanelHeader);

View file

@ -18,15 +18,29 @@
*/
import React from 'react';
import PropTypes from 'prop-types';
import {
EuiContextMenu,
EuiPopover,
EuiButtonIcon,
EuiContextMenu,
EuiContextMenuPanelDescriptor,
EuiPopover,
} from '@elastic/eui';
export function PanelOptionsMenu({ toggleContextMenu, isPopoverOpen, closeContextMenu, panels, isViewMode }) {
export interface PanelOptionsMenuProps {
toggleContextMenu: () => void;
isPopoverOpen: boolean;
closeContextMenu: () => void;
panels: EuiContextMenuPanelDescriptor[];
isViewMode: boolean;
}
export function PanelOptionsMenu({
toggleContextMenu,
isPopoverOpen,
closeContextMenu,
panels,
isViewMode,
}: PanelOptionsMenuProps) {
const button = (
<EuiButtonIcon
iconType={isViewMode ? 'boxesHorizontal' : 'gear'}
@ -49,18 +63,7 @@ export function PanelOptionsMenu({ toggleContextMenu, isPopoverOpen, closeContex
anchorPosition="downRight"
withTitle
>
<EuiContextMenu
initialPanelId="mainMenu"
panels={panels}
/>
<EuiContextMenu initialPanelId="mainMenu" panels={panels} />
</EuiPopover>
);
}
PanelOptionsMenu.propTypes = {
panels: PropTypes.array,
toggleContextMenu: PropTypes.func,
closeContextMenu: PropTypes.func,
isPopoverOpen: PropTypes.bool,
isViewMode: PropTypes.bool.isRequired,
};

View file

@ -17,21 +17,22 @@
* under the License.
*/
import { connect } from 'react-redux';
import PropTypes from 'prop-types';
import { EuiContextMenuPanelDescriptor } from '@elastic/eui';
import * as Redux from 'react-redux';
import { ContainerState, Embeddable } from 'ui/embeddable';
import { panelActionsStore } from '../../store/panel_actions_store';
import { embeddableShape } from 'ui/embeddable';
import { PanelOptionsMenu } from './panel_options_menu';
import {
buildEuiContextMenuPanels,
getCustomizePanelAction,
getEditPanelAction,
getInspectorPanelAction,
getRemovePanelAction,
getCustomizePanelAction,
getToggleExpandPanelAction,
} from './panel_actions';
import { PanelOptionsMenu, PanelOptionsMenuProps } from './panel_options_menu';
import {
closeContextMenu,
deletePanel,
maximizePanel,
minimizePanel,
@ -40,20 +41,49 @@ import {
setVisibleContextMenuPanelId,
} from '../../actions';
import { DashboardContextMenuPanel } from 'ui/dashboard_panel_actions';
import { CoreKibanaState } from '../../../selectors';
import { DashboardViewMode } from '../../dashboard_view_mode';
import {
getContainerState,
getEmbeddable,
getEmbeddableEditUrl,
getEmbeddableTitle,
getMaximizedPanelId,
getPanel,
getEmbeddableTitle,
getContainerState,
getVisibleContextMenuPanelId,
getViewMode,
getVisibleContextMenuPanelId,
PanelId,
} from '../../selectors';
import { DashboardContextMenuPanel } from 'ui/dashboard_panel_actions';
import { DashboardViewMode } from '../../dashboard_view_mode';
const mapStateToProps = ({ dashboard }, { panelId }) => {
interface PanelOptionsMenuContainerDispatchProps {
onDeletePanel: () => void;
onCloseContextMenu: () => void;
openContextMenu: () => void;
onMaximizePanel: () => void;
onMinimizePanel: () => void;
onResetPanelTitle: () => void;
onUpdatePanelTitle: (title: string) => void;
}
interface PanelOptionsMenuContainerOwnProps {
panelId: PanelId;
embeddable?: Embeddable;
}
interface PanelOptionsMenuContainerStateProps {
panelTitle?: string;
editUrl: string | null | undefined;
isExpanded: boolean;
containerState: ContainerState;
visibleContextMenuPanelId: PanelId | undefined;
isViewMode: boolean;
}
const mapStateToProps = (
{ dashboard }: CoreKibanaState,
{ panelId }: PanelOptionsMenuContainerOwnProps
) => {
const embeddable = getEmbeddable(dashboard, panelId);
const panel = getPanel(dashboard, panelId);
const embeddableTitle = getEmbeddableTitle(dashboard, panelId);
@ -75,20 +105,33 @@ const mapStateToProps = ({ dashboard }, { panelId }) => {
* @param embeddableFactory {EmbeddableFactory}
* @param panelId {string}
*/
const mapDispatchToProps = (dispatch, { panelId }) => ({
const mapDispatchToProps = (
dispatch: Redux.Dispatch<CoreKibanaState>,
{ panelId }: PanelOptionsMenuContainerOwnProps
) => ({
onDeletePanel: () => {
dispatch(deletePanel(panelId));
},
closeContextMenu: () => dispatch(setVisibleContextMenuPanelId()),
onCloseContextMenu: () => dispatch(closeContextMenu()),
openContextMenu: () => dispatch(setVisibleContextMenuPanelId(panelId)),
onMaximizePanel: () => dispatch(maximizePanel(panelId)),
onMinimizePanel: () => dispatch(minimizePanel()),
onResetPanelTitle: () => dispatch(resetPanelTitle(panelId)),
onUpdatePanelTitle: (newTitle) => dispatch(setPanelTitle({ title: newTitle, panelId: panelId })),
onUpdatePanelTitle: (newTitle: string) => dispatch(setPanelTitle({ title: newTitle, panelId })),
});
const mergeProps = (stateProps, dispatchProps, ownProps) => {
const { isExpanded, panelTitle, containerState, visibleContextMenuPanelId, isViewMode } = stateProps;
const mergeProps = (
stateProps: PanelOptionsMenuContainerStateProps,
dispatchProps: PanelOptionsMenuContainerDispatchProps,
ownProps: PanelOptionsMenuContainerOwnProps
) => {
const {
isExpanded,
panelTitle,
containerState,
visibleContextMenuPanelId,
isViewMode,
} = stateProps;
const isPopoverOpen = visibleContextMenuPanelId === ownProps.panelId;
const {
onMaximizePanel,
@ -96,16 +139,16 @@ const mergeProps = (stateProps, dispatchProps, ownProps) => {
onDeletePanel,
onResetPanelTitle,
onUpdatePanelTitle,
closeContextMenu,
onCloseContextMenu,
openContextMenu,
} = dispatchProps;
const toggleContextMenu = () => isPopoverOpen ? closeContextMenu() : openContextMenu();
const toggleContextMenu = () => (isPopoverOpen ? onCloseContextMenu() : openContextMenu());
// Outside click handlers will trigger for every closed context menu, we only want to react to clicks external to
// the currently opened menu.
const closeMyContextMenuPanel = () => {
if (isPopoverOpen) {
closeContextMenu();
onCloseContextMenu();
}
};
@ -114,14 +157,14 @@ const mergeProps = (stateProps, dispatchProps, ownProps) => {
closeMyContextMenuPanel();
};
let panels = [];
let panels: EuiContextMenuPanelDescriptor[] = [];
// Don't build the panels if the pop over is not open, or this gets expensive - this function is called once for
// every panel, every time any state changes.
if (isPopoverOpen) {
const contextMenuPanel = new DashboardContextMenuPanel({
title: 'Options',
id: 'mainMenu'
id: 'mainMenu',
});
const actions = [
@ -134,13 +177,18 @@ const mergeProps = (stateProps, dispatchProps, ownProps) => {
onResetPanelTitle,
onUpdatePanelTitle,
title: panelTitle,
closeContextMenu: closeMyContextMenuPanel
closeContextMenu: closeMyContextMenuPanel,
}),
getToggleExpandPanelAction({ isExpanded, toggleExpandedPanel }),
getRemovePanelAction(onDeletePanel),
].concat(panelActionsStore.actions);
panels = buildEuiContextMenuPanels({ contextMenuPanel, actions, embeddable: ownProps.embeddable, containerState });
panels = buildEuiContextMenuPanels({
contextMenuPanel,
actions,
embeddable: ownProps.embeddable,
containerState,
});
}
return {
@ -152,13 +200,14 @@ const mergeProps = (stateProps, dispatchProps, ownProps) => {
};
};
export const PanelOptionsMenuContainer = connect(
export const PanelOptionsMenuContainer = Redux.connect<
PanelOptionsMenuContainerStateProps,
PanelOptionsMenuContainerDispatchProps,
PanelOptionsMenuContainerOwnProps,
PanelOptionsMenuProps,
CoreKibanaState
>(
mapStateToProps,
mapDispatchToProps,
mergeProps,
mergeProps
)(PanelOptionsMenu);
PanelOptionsMenuContainer.propTypes = {
panelId: PropTypes.string.isRequired,
embeddable: embeddableShape,
};

View file

@ -24,7 +24,7 @@ import { EuiButtonEmpty, EuiFieldText, EuiFormRow, keyCodes } from '@elastic/eui
export interface PanelOptionsMenuFormProps {
title?: string;
onReset: () => void;
onUpdatePanelTitle: (newPanelTitle?: string) => void;
onUpdatePanelTitle: (newPanelTitle: string) => void;
onClose: () => void;
}

View file

@ -26,6 +26,11 @@ import { QueryLanguageType } from 'ui/embeddable/types';
import { DashboardViewMode } from '../dashboard_view_mode';
import { PanelId, ViewState } from '../selectors';
const closeContextMenu = (view: ViewState) => ({
...view,
visibleContextMenuPanelId: undefined,
});
const setVisibleContextMenuPanelId = (view: ViewState, panelId: PanelId) => ({
...view,
visibleContextMenuPanelId: panelId,
@ -95,6 +100,8 @@ export const viewReducer: Reducer<ViewState> = (
return maximizePanel(view, action.payload);
case ViewActionTypeKeys.SET_VISIBLE_CONTEXT_MENU_PANEL_ID:
return setVisibleContextMenuPanelId(view, action.payload);
case ViewActionTypeKeys.CLOSE_CONTEXT_MENU:
return closeContextMenu(view);
case ViewActionTypeKeys.UPDATE_HIDE_PANEL_TITLES:
return updateHidePanelTitles(view, action.payload);
case ViewActionTypeKeys.UPDATE_TIME_RANGE:

View file

@ -17,20 +17,16 @@
* under the License.
*/
import { DashboardPanelAction } from 'ui/dashboard_panel_actions';
class PanelActionsStore {
constructor() {
/**
*
* @type {Array.<DashboardPanelAction>}
*/
this.actions = [];
}
public actions: DashboardPanelAction[] = [];
/**
*
* @type {IndexedArray} panelActionsRegistry
*/
initializeFromRegistry(panelActionsRegistry) {
public initializeFromRegistry(panelActionsRegistry: DashboardPanelAction[]) {
panelActionsRegistry.forEach(panelAction => {
this.actions.push(panelAction);
});

View file

@ -17,10 +17,11 @@
* under the License.
*/
import { ReactElement } from 'react';
import { PanelActionAPI } from './types';
interface DashboardContextMenuPanelOptions {
getContent?: (panelActionAPI: PanelActionAPI) => JSX.Element | Element | undefined;
getContent?: (panelActionAPI: PanelActionAPI) => ReactElement<any> | HTMLElement | undefined;
}
interface DashboardContextMenuPanelConfig {
@ -47,7 +48,7 @@ export class DashboardContextMenuPanel {
/**
* Optional, could be composed of actions instead of content.
*/
public getContent(panelActionAPI: PanelActionAPI): JSX.Element | Element | undefined {
public getContent(panelActionAPI: PanelActionAPI): ReactElement<any> | HTMLElement | undefined {
return;
}
}

View file

@ -16,7 +16,7 @@
* specific language governing permissions and limitations
* under the License.
*/
import { EuiContextMenuItemIcon } from '@elastic/eui';
import { DashboardContextMenuPanel } from './dashboard_context_menu_panel';
import { PanelActionAPI } from './types';
@ -54,7 +54,7 @@ interface DashboardPanelActionOptions {
/**
* Optional icon to display to the left of the action.
*/
icon?: Element | JSX.Element;
icon?: EuiContextMenuItemIcon;
}
interface DashboardPanelActionsConfig {
@ -77,7 +77,7 @@ export class DashboardPanelAction {
/**
* Optional icon to display to the left of the action.
*/
public readonly icon?: Element | JSX.Element;
public readonly icon?: EuiContextMenuItemIcon;
/**
* Display name of the action in the menu

View file

@ -24,9 +24,10 @@ import { ContainerState, Embeddable } from 'ui/embeddable';
*/
export interface PanelActionAPI {
/**
* The embeddable that resides inside this action.
* The embeddable that resides inside this action. It's possible it's undefined if the embeddable has not been returned from
* the EmbeddableFactory yet.
*/
embeddable: Embeddable;
embeddable?: Embeddable;
/**
* Information about the current state of the panel and dashboard.

View file

@ -69,7 +69,7 @@ export interface ContainerState {
/**
* A way to override the underlying embeddable title and supply a title at the panel level.
*/
customTitle: string | undefined;
customTitle?: string;
}
export interface EmbeddableState {

View file

@ -494,6 +494,13 @@
"@types/node" "*"
"@types/react" "*"
"@types/react-redux@^5.0.6":
version "5.0.21"
resolved "https://registry.yarnpkg.com/@types/react-redux/-/react-redux-5.0.21.tgz#98a3a371dfc22c894889f660d7515717639d20f4"
dependencies:
"@types/react" "*"
redux "^3.6.0"
"@types/react@*", "@types/react@^16.3.14":
version "16.3.14"
resolved "https://registry.yarnpkg.com/@types/react/-/react-16.3.14.tgz#f90ac6834de172e13ecca430dcb6814744225d36"
@ -11502,7 +11509,7 @@ redux-thunk@2.3.0:
version "2.3.0"
resolved "https://registry.yarnpkg.com/redux-thunk/-/redux-thunk-2.3.0.tgz#51c2c19a185ed5187aaa9a2d08b666d0d6467622"
redux@3.7.2:
redux@3.7.2, redux@^3.6.0:
version "3.7.2"
resolved "https://registry.yarnpkg.com/redux/-/redux-3.7.2.tgz#06b73123215901d25d065be342eb026bc1c8537b"
dependencies: