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

Drilldown count tooltip #65105

Merged
merged 12 commits into from
May 8, 2020
Merged
Original file line number Diff line number Diff line change
Expand Up @@ -62,16 +62,32 @@ function renderNotifications(
notifications: Array<Action<EmbeddableContext>>,
embeddable: IEmbeddable
) {
return notifications.map(notification => (
<EuiNotificationBadge
data-test-subj={`embeddablePanelNotification-${notification.id}`}
key={notification.id}
style={{ marginTop: '4px', marginRight: '4px' }}
onClick={() => notification.execute({ embeddable })}
>
{notification.getDisplayName({ embeddable })}
</EuiNotificationBadge>
));
return notifications.map(notification => {
const context = { embeddable };

let badge = (
<EuiNotificationBadge
data-test-subj={`embeddablePanelNotification-${notification.id}`}
key={notification.id}
style={{ marginTop: '4px', marginRight: '4px' }}
onClick={() => notification.execute(context)}
>
{notification.getDisplayName(context)}
</EuiNotificationBadge>
);

const tooltip = notification.getDisplayNameTooltip!(context);

if (tooltip) {
badge = (
<EuiToolTip position="left" delay="regular" content={tooltip}>
streamich marked this conversation as resolved.
Show resolved Hide resolved
{badge}
</EuiToolTip>
);
}

return badge;
});
}

function renderTooltip(description: string) {
Expand Down
5 changes: 5 additions & 0 deletions src/plugins/ui_actions/public/actions/action_internal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,11 @@ export class ActionInternal<A extends ActionDefinition = ActionDefinition>
return this.definition.getDisplayName(context);
}

public getDisplayNameTooltip(context: Context<A>): string {
if (!this.definition.getDisplayNameTooltip) return '';
return this.definition.getDisplayNameTooltip(context);
}

public async isCompatible(context: Context<A>): Promise<boolean> {
if (!this.definition.isCompatible) return true;
return await this.definition.isCompatible(context);
Expand Down
6 changes: 6 additions & 0 deletions src/plugins/ui_actions/public/util/presentable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,12 @@ export interface Presentable<Context extends object = object> {
*/
getDisplayName(context: Context): string;

/**
* Returns tooltip text which should be displayed when user hovers this object.
* Should return empty string if tooltip should not be displayed.
*/
getDisplayNameTooltip(context: Context): string;

/**
* This method should return a link if this item can be clicked on. The link
* is used to navigate user if user middle-clicks it or Ctrl + clicks or
Expand Down
1 change: 1 addition & 0 deletions x-pack/.i18nrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
"xpack.dashboardMode": "legacy/plugins/dashboard_mode",
"xpack.data": "plugins/data_enhanced",
"xpack.drilldowns": "plugins/drilldowns",
"xpack.embeddableEnhanced": "plugins/embeddable_enhanced",
"xpack.endpoint": "plugins/endpoint",
"xpack.features": "plugins/features",
"xpack.fileUpload": "plugins/file_upload",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,40 @@ describe('PanelNotificationsAction', () => {
});
});

describe('getDisplayNameTooltip', () => {
test('returns empty string if embeddable has no event', async () => {
const context = createContext();
const action = new PanelNotificationsAction();

const name = await action.getDisplayNameTooltip(context);
expect(name).toBe('');
});

test('returns "1 drilldown" if embeddable has one event', async () => {
const context = createContext([{}]);
const action = new PanelNotificationsAction();

const name = await action.getDisplayNameTooltip(context);
expect(name).toBe('Panel has 1 drilldown');
});

test('returns "2 drilldowns" if embeddable has two events', async () => {
const context = createContext([{}, {}]);
const action = new PanelNotificationsAction();

const name = await action.getDisplayNameTooltip(context);
expect(name).toBe('Panel has 2 drilldowns');
});

test('returns "3 drilldowns" if embeddable has three events', async () => {
const context = createContext([{}, {}, {}]);
const action = new PanelNotificationsAction();

const name = await action.getDisplayNameTooltip(context);
expect(name).toBe('Panel has 3 drilldowns');
});
});

describe('isCompatible', () => {
test('returns false if not in "edit" mode', async () => {
const context = createContext([{}]);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,26 @@
* you may not use this file except in compliance with the Elastic License.
*/

import { i18n } from '@kbn/i18n';
import { UiActionsActionDefinition as ActionDefinition } from '../../../../../src/plugins/ui_actions/public';
import { ViewMode } from '../../../../../src/plugins/embeddable/public';
import { EnhancedEmbeddableContext, EnhancedEmbeddable } from '../types';

export const txtOneDrilldown = i18n.translate(
'xpack.embeddableEnhanced.actions.panelNotifications.oneDrilldown',
{
defaultMessage: 'Panel has 1 drilldown',
}
);

export const txtManyDrilldowns = (count: number) =>
i18n.translate('xpack.embeddableEnhanced.actions.panelNotifications.manyDrilldowns', {
defaultMessage: 'Panel has {count} drilldowns',
values: {
count: String(count),
},
});

export const ACTION_PANEL_NOTIFICATIONS = 'ACTION_PANEL_NOTIFICATIONS';

/**
Expand All @@ -25,6 +41,11 @@ export class PanelNotificationsAction implements ActionDefinition<EnhancedEmbedd
return String(this.getEventCount(embeddable));
};

public readonly getDisplayNameTooltip = ({ embeddable }: EnhancedEmbeddableContext) => {
const count = this.getEventCount(embeddable);
return !count ? '' : count === 1 ? txtOneDrilldown : txtManyDrilldowns(count);
};

public readonly isCompatible = async ({ embeddable }: EnhancedEmbeddableContext) => {
if (embeddable.getInput().viewMode !== ViewMode.EDIT) return false;
return this.getEventCount(embeddable) > 0;
Expand Down