[Drilldowns] Beta badge support. Mark URL Drilldown as Beta (#75654)

Team agreed that we'd like to release URL drilldown MVP as Beta.

Reasons for it:
1. Caveats in current URL drilldown UX (dummy values in preview, too vague triggers, {{event.points}} hack). It might that improving those would require a breaking change in an API. We will do our best to handle changes with migrations, but there could be edge cases we won't be able to cover.
2. We decided not to rush with extending url templating capabilities with more helpers. We could find out from early feedback that essential helpers are required. Even though this won't be breaking, worth mentioning here.
3. Since URL drilldown is a new feature and relies on user's input, we might get early feedback that would required us for a significant changes in the feature. Make it Beta gives us more room for a pivot in this case.
4. API Action concept might change how we reason about URL drilldown

Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>
This commit is contained in:
Anton Dosov 2020-09-18 11:10:42 +02:00 committed by GitHub
parent 9a0dfcff04
commit 827ee5c406
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 78 additions and 2 deletions

View file

@ -1,3 +1,4 @@
[role="xpack"]
[[drilldowns]]
== Use drilldowns for dashboard actions

View file

@ -1,6 +1,8 @@
[[url-drilldown]]
=== URL drilldown
beta[]
The URL drilldown allows you to navigate from a dashboard to an internal or external URL.
The destination URL can be dynamic, depending on the dashboard context or users interaction with a visualization.

View file

@ -51,6 +51,7 @@ export class UrlDrilldown implements Drilldown<Config, UrlTrigger, ActionFactory
readonly minimalLicense = 'gold';
readonly licenseFeatureName = 'URL drilldown';
readonly isBeta = true;
public readonly getDisplayName = () => txtUrlDrilldownDisplayName;

View file

@ -82,3 +82,18 @@ test('If not enough license, button is disabled', () => {
expect(screen.getByText(/Go to URL/i)).toBeDisabled();
});
test('if action is beta, beta badge is shown', () => {
const betaUrl = new ActionFactory(
{
...urlDrilldownActionFactory,
isBeta: true,
},
{
getLicense: () => licensingMock.createLicense(),
getFeatureUsageStart: () => licensingMock.createStart().featureUsage,
}
);
const screen = render(<Demo actionFactories={[dashboardFactory, betaUrl]} />);
expect(screen.getByText(/Beta/i)).toBeVisible();
});

View file

@ -19,9 +19,12 @@ import {
EuiTextColor,
EuiTitle,
EuiLink,
EuiBetaBadge,
} from '@elastic/eui';
import { FormattedMessage } from '@kbn/i18n/react';
import {
txtBetaActionFactoryLabel,
txtBetaActionFactoryTooltip,
txtChangeButton,
txtTriggerPickerHelpText,
txtTriggerPickerLabel,
@ -255,7 +258,15 @@ const SelectedActionFactory: React.FC<SelectedActionFactoryProps> = ({
)}
<EuiFlexItem grow={true}>
<EuiText>
<h4>{actionFactory.getDisplayName(context)}</h4>
<h4>
{actionFactory.getDisplayName(context)}{' '}
{actionFactory.isBeta && (
<EuiBetaBadge
label={txtBetaActionFactoryLabel}
tooltipContent={txtBetaActionFactoryTooltip}
/>
)}
</h4>
</EuiText>
</EuiFlexItem>
{showDeselect && (
@ -350,6 +361,10 @@ const ActionFactorySelector: React.FC<ActionFactorySelectorProps> = ({
data-test-subj={`${TEST_SUBJ_ACTION_FACTORY_ITEM}-${actionFactory.id}`}
onClick={() => onActionFactorySelected(actionFactory)}
disabled={!actionFactory.isCompatibleLicense()}
betaBadgeLabel={actionFactory.isBeta ? txtBetaActionFactoryLabel : undefined}
betaBadgeTooltipContent={
actionFactory.isBeta ? txtBetaActionFactoryTooltip : undefined
}
>
{actionFactory.getIconType(context) && (
<EuiIcon type={actionFactory.getIconType(context)!} size="m" />

View file

@ -33,3 +33,17 @@ export const txtTriggerPickerHelpTooltip = i18n.translate(
defaultMessage: 'Determines when the drilldown appears in context menu',
}
);
export const txtBetaActionFactoryLabel = i18n.translate(
'xpack.uiActionsEnhanced.components.actionWizard.betaActionLabel',
{
defaultMessage: `Beta`,
}
);
export const txtBetaActionFactoryTooltip = i18n.translate(
'xpack.uiActionsEnhanced.components.actionWizard.betaActionTooltip',
{
defaultMessage: `This action is in beta and is subject to change. The design and code is less mature than official GA features and is being provided as-is with no warranties. Beta features are not subject to the support SLA of official GA features. Please help us by reporting any bugs or providing other feedback.`,
}
);

View file

@ -36,6 +36,12 @@ export interface DrilldownDefinition<
*/
id: string;
/**
* Is this action factory not GA?
* Adds a beta badge on a list item representing this ActionFactory
*/
readonly isBeta?: boolean;
/**
* Minimal license level
* Empty means no restrictions

View file

@ -19,7 +19,8 @@ export const txtUrlTemplatePlaceholder = i18n.translate(
export const txtUrlPreviewHelpText = i18n.translate(
'xpack.uiActionsEnhanced.drilldowns.urlDrilldownCollectConfig.urlPreviewHelpText',
{
defaultMessage: 'Please note that \\{\\{event.*\\}\\} variables replaced by dummy values.',
defaultMessage:
'Please note that in preview \\{\\{event.*\\}\\} variables are substituted with dummy values.',
}
);

View file

@ -114,3 +114,15 @@ describe('License & ActionFactory', () => {
});
});
});
describe('isBeta', () => {
test('false by default', async () => {
const factory = createActionFactory();
expect(factory.isBeta).toBe(false);
});
test('true', async () => {
const factory = createActionFactory({ isBeta: true });
expect(factory.isBeta).toBe(true);
});
});

View file

@ -46,6 +46,7 @@ export class ActionFactory<
}
public readonly id = this.def.id;
public readonly isBeta = this.def.isBeta ?? false;
public readonly minimalLicense = this.def.minimalLicense;
public readonly licenseFeatureName = this.def.licenseFeatureName;
public readonly order = this.def.order || 0;

View file

@ -46,6 +46,12 @@ export interface ActionFactoryDefinition<
*/
licenseFeatureName?: string;
/**
* Is this action factory not GA?
* Adds a beta badge on a list item representing this ActionFactory
*/
readonly isBeta?: boolean;
/**
* This method should return a definition of a new action, normally used to
* register it in `ui_actions` registry.

View file

@ -89,6 +89,7 @@ export class UiActionsServiceEnhancements {
ExecutionContext extends TriggerContextMapping[SupportedTriggers] = TriggerContextMapping[SupportedTriggers]
>({
id: factoryId,
isBeta,
order,
CollectConfig,
createConfig,
@ -109,6 +110,7 @@ export class UiActionsServiceEnhancements {
ExecutionContext
> = {
id: factoryId,
isBeta,
minimalLicense,
licenseFeatureName,
order,