mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 09:48:58 -04:00
Drilldown count tooltip (#65105)
* feat: 🎸 add tooltip ability to ui_actions * feat: 🎸 add tooltip support to drilldown count notification * test: 💍 add drilldown tooltip text tests * fix: 🐛 improve tooltip texts * fix: 🐛 put tooltip on top * fix: 🐛 add missing method to ActionFactory * fix: 🐛 improve handling of optional method
This commit is contained in:
parent
e35a74375a
commit
86bafec3a4
7 changed files with 99 additions and 10 deletions
|
@ -62,16 +62,34 @@ 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>
|
||||
);
|
||||
|
||||
if (notification.getDisplayNameTooltip) {
|
||||
const tooltip = notification.getDisplayNameTooltip(context);
|
||||
|
||||
if (tooltip) {
|
||||
badge = (
|
||||
<EuiToolTip position="top" delay="regular" content={tooltip}>
|
||||
{badge}
|
||||
</EuiToolTip>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return badge;
|
||||
});
|
||||
}
|
||||
|
||||
function renderTooltip(description: string) {
|
||||
|
|
|
@ -48,6 +48,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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -42,6 +42,10 @@ export class ActionFactory<
|
|||
return this.def.getDisplayName(context);
|
||||
}
|
||||
|
||||
public getDisplayNameTooltip(context: FactoryContext): string {
|
||||
return '';
|
||||
}
|
||||
|
||||
public async isCompatible(context: FactoryContext): Promise<boolean> {
|
||||
if (!this.def.isCompatible) return true;
|
||||
return await this.def.isCompatible(context);
|
||||
|
|
|
@ -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([{}]);
|
||||
|
|
|
@ -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';
|
||||
|
||||
/**
|
||||
|
@ -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;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue