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

Per panel time range #39937

Closed
Show file tree
Hide file tree
Changes from 15 commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
14ed5b5
Per panel time range
stacey-gammon Jul 12, 2019
5906fb6
fix typescript
stacey-gammon Jul 24, 2019
d16646d
add space between badge and title
stacey-gammon Jul 25, 2019
c6cd8de
remove unneccessary iconOnClick* fns
stacey-gammon Jul 25, 2019
997d356
Merge branch 'master' of github.com:elastic/kibana into 2019-06-28-ti…
stacey-gammon Jul 25, 2019
d699c58
Use common time ranges from advanced settings
stacey-gammon Jul 25, 2019
7f3d40c
Only add space after title if title is showing
stacey-gammon Jul 25, 2019
a874332
fix: type errors
stacey-gammon Jul 25, 2019
9ccd033
put xpack i18n links back in right place
stacey-gammon Jul 25, 2019
28aef75
Merge branch 'master' of github.com:elastic/kibana into 2019-06-28-ti…
stacey-gammon Jul 26, 2019
ab3f7dd
Merge branch 'master' of github.com:elastic/kibana into 2019-06-28-ti…
stacey-gammon Jul 29, 2019
bbf4b8d
Fix flex items, remove spaces
stacey-gammon Jul 29, 2019
36c3542
use right string for detecting input control vis types
stacey-gammon Jul 29, 2019
eab24fc
Merge branch 'master' of github.com:elastic/kibana into 2019-06-28-ti…
stacey-gammon Jul 29, 2019
94e50da
Merge branch 'master' of github.com:elastic/kibana into 2019-06-28-ti…
stacey-gammon Jul 31, 2019
376db13
Merge branch 'master' of github.com:elastic/kibana into 2019-06-28-ti…
stacey-gammon Aug 5, 2019
f47c8a4
delete empty file
stacey-gammon Aug 5, 2019
b72106b
remove unneccessary checks
stacey-gammon Aug 5, 2019
ace9253
hide time range override action for markdown vis
stacey-gammon Aug 5, 2019
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
Original file line number Diff line number Diff line change
Expand Up @@ -99,5 +99,5 @@ test('Returns title', async () => {

test('Returns an icon', async () => {
const action = new ExpandPanelAction();
expect(action.getIcon({ embeddable })).toBeDefined();
expect(action.getIconType({ embeddable })).toBeDefined();
});
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,7 @@
* under the License.
*/

import { EuiIcon } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import React from 'react';
import {
Action,
IEmbeddable,
Expand Down Expand Up @@ -72,12 +70,12 @@ export class ExpandPanelAction extends Action {
);
}

public getIcon({ embeddable }: ActionContext) {
public getIconType({ embeddable }: ActionContext) {
if (!embeddable.parent || !isDashboard(embeddable.parent)) {
throw new IncompatibleActionError();
}
// TODO: use 'minimize' when an eui-icon of such is available.
return <EuiIcon type={isExpanded(embeddable) ? 'expand' : 'expand'} />;
return isExpanded(embeddable) ? 'expand' : 'expand';
}

public async isCompatible({ embeddable }: ActionContext) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,6 @@
* under the License.
*/

import { EuiContextMenuItemIcon } from '@elastic/eui';

import { IEmbeddable } from '../embeddables';

export interface ActionContext<
Expand All @@ -45,9 +43,7 @@ export abstract class Action<
/**
* Optional icon that can be displayed along with the title.
*/
public getIcon(
context: ActionContext<TEmbeddable, TTriggerContext>
): EuiContextMenuItemIcon | undefined {
public getIconType(context: ActionContext<TEmbeddable, TTriggerContext>): string | undefined {
return undefined;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ function convertPanelActionToContextMenuItem({
}): EuiContextMenuPanelItemDescriptor {
const menuPanelItem: EuiContextMenuPanelItemDescriptor = {
name: action.getDisplayName(actionContext),
icon: action.getIcon(actionContext),
icon: action.getIconType(actionContext),
panel: _.get(action, 'childContextMenuPanel.id'),
'data-test-subj': `embeddablePanelAction-${action.id}`,
};
Expand Down
1 change: 1 addition & 0 deletions src/legacy/core_plugins/embeddable_api/public/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ export {
triggerRegistry,
executeTriggerActions,
CONTEXT_MENU_TRIGGER,
PANEL_BADGE_TRIGGER,
attachAction,
} from './triggers';

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,15 @@ import React from 'react';
import { Subscription } from 'rxjs';
import { buildContextMenuForActions } from '../context_menu_actions';

import { CONTEXT_MENU_TRIGGER, triggerRegistry } from '../triggers';
import { CONTEXT_MENU_TRIGGER, triggerRegistry, PANEL_BADGE_TRIGGER } from '../triggers';
import { IEmbeddable } from '../embeddables/i_embeddable';
import { ViewMode } from '../types';

import { RemovePanelAction } from './panel_header/panel_actions';
import { AddPanelAction } from './panel_header/panel_actions/add_panel/add_panel_action';
import { CustomizePanelTitleAction } from './panel_header/panel_actions/customize_title/customize_panel_action';
import { PanelHeader } from './panel_header/panel_header';
import { actionRegistry } from '../actions';
import { actionRegistry, Action } from '../actions';
import { InspectPanelAction } from './panel_header/panel_actions/inspect_panel_action';
import { EditPanelAction } from './panel_header/panel_actions/edit_panel_action';
import { getActionsForTrigger } from '../get_actions_for_trigger';
Expand All @@ -45,6 +45,7 @@ interface State {
viewMode: ViewMode;
hidePanelTitles: boolean;
closeContextMenu: boolean;
badges: Action[];
}

export class EmbeddablePanel extends React.Component<Props, State> {
Expand All @@ -67,12 +68,13 @@ export class EmbeddablePanel extends React.Component<Props, State> {
viewMode,
hidePanelTitles,
closeContextMenu: false,
badges: [],
};

this.embeddableRoot = React.createRef();
}

public componentWillMount() {
public async componentWillMount() {
this.mounted = true;
const { embeddable } = this.props;
const { parent } = embeddable;
Expand All @@ -82,6 +84,7 @@ export class EmbeddablePanel extends React.Component<Props, State> {
this.setState({
viewMode: embeddable.getInput().viewMode ? embeddable.getInput().viewMode : ViewMode.EDIT,
});
this.refreshBadges();
}
});

Expand All @@ -91,11 +94,29 @@ export class EmbeddablePanel extends React.Component<Props, State> {
this.setState({
hidePanelTitles: Boolean(parent.getInput().hidePanelTitles),
});
this.refreshBadges();
}
});
}
}

private async refreshBadges() {
const badges = await getActionsForTrigger(
actionRegistry,
triggerRegistry,
PANEL_BADGE_TRIGGER,
{
embeddable: this.props.embeddable,
}
);

if (this.mounted) {
this.setState({
badges,
});
}
}

public componentWillUnmount() {
this.mounted = false;
if (this.subscription) {
Expand All @@ -122,6 +143,7 @@ export class EmbeddablePanel extends React.Component<Props, State> {
const classes = classNames('embPanel', {
'embPanel--editing': !viewOnlyMode,
});

const title = this.props.embeddable.getTitle();
return (
<EuiPanel className={classes} data-test-subj="embeddablePanel" paddingSize="none">
Expand All @@ -131,6 +153,8 @@ export class EmbeddablePanel extends React.Component<Props, State> {
isViewMode={viewOnlyMode}
closeContextMenu={this.state.closeContextMenu}
title={title}
badges={this.state.badges}
embeddable={this.props.embeddable}
/>
<div className="embPanel__content" ref={this.embeddableRoot} />
</EuiPanel>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -116,5 +116,5 @@ test('Returns title', async () => {

test('Returns an icon', async () => {
const action = new AddPanelAction();
expect(action.getIcon()).toBeDefined();
expect(action.getIconType()).toBeDefined();
});
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,6 @@
* specific language governing permissions and limitations
* under the License.
*/

import { EuiIcon } from '@elastic/eui';
import React from 'react';

import { i18n } from '@kbn/i18n';
import { ViewMode } from '../../../../types';
import { Action, ActionContext } from '../../../../actions';
Expand All @@ -40,8 +36,8 @@ export class AddPanelAction extends Action {
});
}

public getIcon() {
return <EuiIcon type="plusInCircleFilled" />;
public getIconType() {
return 'plusInCircleFilled';
}

public async isCompatible({ embeddable }: ActionContext) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,6 @@
* under the License.
*/

import { EuiIcon } from '@elastic/eui';
import React from 'react';
import { i18n } from '@kbn/i18n';
import { Action, ActionContext } from '../../../../actions';
import { ViewMode } from '../../../../types';
Expand All @@ -45,8 +43,8 @@ export class CustomizePanelTitleAction extends Action {
});
}

public getIcon() {
return <EuiIcon type="pencil" />;
public getIconType() {
return 'pencil';
}

public async isCompatible({ embeddable }: ActionContext) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,7 @@
* under the License.
*/

import React from 'react';
import { i18n } from '@kbn/i18n';
import { EuiIcon } from '@elastic/eui';

import { embeddableFactories } from '../../../embeddables/embeddable_factories_registry';
import { Action, ActionContext } from '../../../actions';
Expand Down Expand Up @@ -48,8 +46,8 @@ export class EditPanelAction extends Action {
});
}

getIcon() {
return <EuiIcon type="pencil" />;
getIconType() {
return 'pencil';
}

public async isCompatible({ embeddable }: ActionContext) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -125,5 +125,5 @@ test('Returns title', async () => {

test('Returns an icon', async () => {
const inspectAction = new InspectPanelAction();
expect(inspectAction.getIcon()).toBeDefined();
expect(inspectAction.getIconType()).toBeDefined();
});
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,6 @@
* specific language governing permissions and limitations
* under the License.
*/

import { EuiIcon } from '@elastic/eui';
import React from 'react';

import { i18n } from '@kbn/i18n';
import { Inspector } from 'ui/inspector';
import { Action, ActionContext } from '../../../actions';
Expand All @@ -39,8 +35,8 @@ export class InspectPanelAction extends Action {
});
}

public getIcon() {
return <EuiIcon type="inspect" />;
public getIconType() {
return 'inspect';
}

public async isCompatible({ embeddable }: ActionContext) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,5 +103,5 @@ test('Returns title', async () => {

test('Returns an icon', async () => {
const action = new RemovePanelAction();
expect(action.getIcon()).toBeDefined();
expect(action.getIconType()).toBeDefined();
});
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,7 @@
* specific language governing permissions and limitations
* under the License.
*/
import React from 'react';
import { i18n } from '@kbn/i18n';
import { EuiIcon } from '@elastic/eui';
import { ContainerInput, IContainer } from '../../../containers';
import { ViewMode } from '../../../types';
import { Action, ActionContext, IncompatibleActionError } from '../../../actions';
Expand Down Expand Up @@ -49,8 +47,8 @@ export class RemovePanelAction extends Action {
});
}

public getIcon() {
return <EuiIcon type="trash" />;
public getIconType() {
return 'trash';
}

public async isCompatible({ embeddable }: ActionContext) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,37 +17,59 @@
* under the License.
*/

import { EuiContextMenuPanelDescriptor } from '@elastic/eui';
import { EuiContextMenuPanelDescriptor, EuiBadge } from '@elastic/eui';
import { InjectedIntl, injectI18n } from '@kbn/i18n/react';
import classNames from 'classnames';
import React from 'react';
import { PanelOptionsMenu } from './panel_options_menu';
import { Action } from '../../actions';
import { IEmbeddable } from '../../embeddables';

export interface PanelHeaderProps {
title?: string;
isViewMode: boolean;
hidePanelTitles: boolean;
getActionContextMenuPanel: () => Promise<EuiContextMenuPanelDescriptor>;
closeContextMenu: boolean;
badges: Action[];
embeddable: IEmbeddable;
}

interface PanelHeaderUiProps extends PanelHeaderProps {
intl: InjectedIntl;
}

function renderBadges(badges: Action[], embeddable: IEmbeddable) {
return badges.map(badge => (
<EuiBadge
key={badge.id}
iconType={badge.getIconType({ embeddable })}
onClick={() => badge.execute({ embeddable })}
onClickAriaLabel={badge.getDisplayName({ embeddable })}
>
{badge.getDisplayName({ embeddable })}
</EuiBadge>
));
}

function PanelHeaderUi({
title,
isViewMode,
hidePanelTitles,
getActionContextMenuPanel,
intl,
closeContextMenu,
badges,
embeddable,
}: PanelHeaderUiProps) {
const classes = classNames('embPanel__header', {
'embPanel__header--floater': !title || hidePanelTitles,
'embPanel__header--floater': (!title || hidePanelTitles) && badges.length === 0,
});

if (isViewMode && (!title || hidePanelTitles)) {
const showTitle = !isViewMode || (title && !hidePanelTitles);
const showPanelBar = badges.length > 0 || showTitle;

if (!showPanelBar) {
return (
<div className={classes}>
<PanelOptionsMenu
Expand Down Expand Up @@ -78,7 +100,8 @@ function PanelHeaderUi({
}
)}
>
{hidePanelTitles ? '' : title}
{showTitle ? `${title} ` : ''}
{renderBadges(badges, embeddable)}
cchaos marked this conversation as resolved.
Show resolved Hide resolved
</div>

<PanelOptionsMenu
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,17 @@ export { executeTriggerActions } from './execute_trigger_actions';

export const CONTEXT_MENU_TRIGGER = 'CONTEXT_MENU_TRIGGER';
export const APPLY_FILTER_TRIGGER = 'FITLER_TRIGGER';
export const PANEL_BADGE_TRIGGER = 'PANEL_BADGE_TRIGGER';

import { Trigger } from '../types';
export const triggerRegistry = new Map<string, Trigger>();

triggerRegistry.set(PANEL_BADGE_TRIGGER, {
id: PANEL_BADGE_TRIGGER,
title: 'Panel badges',
actionIds: [],
});

triggerRegistry.set(CONTEXT_MENU_TRIGGER, {
id: CONTEXT_MENU_TRIGGER,
title: 'Context menu',
Expand Down
Loading