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

Drilldowns #59632

Merged
merged 109 commits into from
Mar 24, 2020
Merged
Show file tree
Hide file tree
Changes from 14 commits
Commits
Show all changes
109 commits
Select commit Hold shift + click to select a range
502a60a
Add drilldown wizard components
Dosant Mar 9, 2020
a7ed6ab
Dynamic actions (#58216)
streamich Mar 9, 2020
43583c2
Drilldown context menu (#59638)
streamich Mar 9, 2020
e145241
Add basic ActionFactoryService. Pass data from it into components ins…
Dosant Mar 9, 2020
81e6bcb
Dashboard x pack (#59653)
streamich Mar 9, 2020
1f2cc4c
feat: 🎸 "implement" registerDrilldown() method
streamich Mar 9, 2020
86885c4
fix ConfigurableBaseConfig type
Dosant Mar 9, 2020
6463118
Implement connected flyout_manage_drilldowns component
Dosant Mar 9, 2020
dcacf10
Merge branch 'master' of github.com:elastic/kibana into drilldowns
Dosant Mar 9, 2020
26dfa30
Merge branch 'master' of github.com:elastic/kibana into drilldowns
Dosant Mar 10, 2020
d3cd9e8
Simplify connected flyout manage drilldowns component. Remove interme…
Dosant Mar 10, 2020
1077518
Merge branch 'master' of github.com:elastic/kibana into drilldowns
Dosant Mar 10, 2020
840e873
clean up data-testid workaround in new components
Dosant Mar 10, 2020
f057979
Connect welcome message to storage
Dosant Mar 10, 2020
d60fc96
require `context` in Presentable. drill context down through wizard c…
Dosant Mar 10, 2020
140c5dc
Drilldown factory (#59823)
streamich Mar 10, 2020
b8cf696
Drilldown registration (#59834)
streamich Mar 10, 2020
2e65fd0
Drilldown events 3 (#59854)
streamich Mar 11, 2020
beb053b
Drilldown events 4 (#59876)
streamich Mar 11, 2020
ab6fb4b
Drilldown events 5 (#59885)
streamich Mar 11, 2020
12b8a3f
Merge remote-tracking branch 'upstream/master' into drilldowns
streamich Mar 11, 2020
27b1854
Merge branch 'master' into drilldowns
elasticmachine Mar 11, 2020
0f3ff3e
basic integration of components with dynamicActionManager
Dosant Mar 11, 2020
5009f71
Merge branch 'drilldowns' of github.com:elastic/kibana into drilldowns
Dosant Mar 11, 2020
f176550
fix: 🐛 don't overwrite explicitInput with combined input (#59938)
streamich Mar 11, 2020
4a4766e
display drilldown count in embeddable edit mode
mattkime Mar 11, 2020
0c14ff0
display drilldown count in embeddable edit mode
mattkime Mar 11, 2020
0d4bee2
improve wizard components. more tests.
Dosant Mar 12, 2020
ae98c6b
partial progress, dashboard drilldowns (#59977)
mattkime Mar 12, 2020
3200151
Manage drilldowns toasts. Add basic error handling.
Dosant Mar 12, 2020
ff4e9ad
support order in action factory selector
Dosant Mar 12, 2020
c7d4aa6
fix column order in manage drilldowns list
Dosant Mar 12, 2020
c731afa
remove accidental debug info
Dosant Mar 12, 2020
7d47d9f
Merge branch 'master' into drilldowns
elasticmachine Mar 12, 2020
f2d9056
bunch of nit ui fixes
Dosant Mar 13, 2020
8ad5cd4
Drilldowns reactive action manager (#60099)
streamich Mar 13, 2020
3c94332
Merge branch 'master' into drilldowns
elasticmachine Mar 13, 2020
6f59d1a
Drilldowns various 2 (#60103)
streamich Mar 13, 2020
66e791e
test: 💍 stub DynamicActionManager tests (#60104)
streamich Mar 13, 2020
1f238fe
Drilldowns review 1 (#60139)
streamich Mar 13, 2020
a772987
chore: 🤖 catch up with master
streamich Mar 16, 2020
e66513c
fix: 🐛 correct merge
streamich Mar 16, 2020
6efef2b
Drilldowns various 4 (#60264)
streamich Mar 16, 2020
537f8ee
workaround issue with closing flyout when navigating away
Dosant Mar 16, 2020
0ad8933
fix react key issue in action_wizard
Dosant Mar 16, 2020
94894c1
don’t open 2 flyouts
Dosant Mar 16, 2020
65f5414
fix action order
Dosant Mar 16, 2020
d3487ab
Merge branch 'master' into drilldowns
elasticmachine Mar 16, 2020
a405f83
Drilldowns reload stored (#60336)
streamich Mar 16, 2020
894aec7
chore: 🤖 catch up with master
streamich Mar 16, 2020
cfdab22
Drilldowns triggers (#60339)
streamich Mar 16, 2020
e96f815
Merge branch 'master' into drilldowns
elasticmachine Mar 16, 2020
62edd23
fix: 🐛 stop infinite re-rendering
streamich Mar 17, 2020
7a7beeb
Drilldowns multitrigger (#60357)
streamich Mar 17, 2020
5418305
"Create drilldown" flyout - design cleanup (#60309)
andreadelrio Mar 17, 2020
45f6f4d
basic unit tests for flyout_create_drildown action
Dosant Mar 17, 2020
ceb5cfe
Drilldowns finalize (#60371)
streamich Mar 17, 2020
4646ad2
Merge branch 'master' into drilldowns
elasticmachine Mar 17, 2020
6d0b8cb
basic unit tests for drilldown actions
Dosant Mar 17, 2020
ab3f4bf
Merge branch 'drilldowns' of github.com:elastic/kibana into drilldowns
Dosant Mar 17, 2020
5b4434b
Merge branch 'master' of github.com:elastic/kibana into drilldowns
mattkime Mar 17, 2020
65fae5e
Merge branch 'master' into drilldowns
mattkime Mar 17, 2020
6229d4f
Merge branch 'drilldowns' of github.com:elastic/kibana into drilldowns
mattkime Mar 17, 2020
1252f37
Drilldowns finalize 2 (#60510)
streamich Mar 18, 2020
243e5ce
Merge branch 'master' into drilldowns
elasticmachine Mar 19, 2020
469250f
feat: 🎸 don't show "OPTIONS" title on drilldown context menus
streamich Mar 19, 2020
c73319a
feat: 🎸 add server-side for x-pack dashboard plugin
streamich Mar 19, 2020
2280fdf
feat: 🎸 disable Drilldowns for TSVB
streamich Mar 19, 2020
adcb0a3
feat: 🎸 enable drilldowns on kibana.yml feature flag
streamich Mar 19, 2020
9e22e55
feat: 🎸 add feature flag comment to kibana.yml
streamich Mar 19, 2020
c3e6a61
Merge branch 'master' into drilldowns
elasticmachine Mar 19, 2020
ed8580a
feat: 🎸 remove places from drilldown interface
streamich Mar 20, 2020
73a91f3
refactor: 💡 remove place in factory context
streamich Mar 20, 2020
4d500b5
chore: 🤖 remove doExecute
streamich Mar 20, 2020
054fc8f
remove not needed now error_configure_action component
Dosant Mar 20, 2020
1e9efde
remove workaround for storybook
Dosant Mar 20, 2020
1a3e67b
feat: 🎸 improve DrilldownDefinition interface
streamich Mar 20, 2020
d1666ca
style: 💄 replace any by unknown
streamich Mar 20, 2020
32466a5
chore: 🤖 remove any
streamich Mar 20, 2020
df10920
chore: 🤖 make isConfigValid return type a boolean
streamich Mar 20, 2020
fb3bde9
Merge remote-tracking branch 'upstream/drilldowns' into drilldowns
streamich Mar 20, 2020
ce39459
Merge branch 'master' into drilldowns
elasticmachine Mar 20, 2020
d480655
refactor: 💡 move getDisplayName to factory, remove deprecated
streamich Mar 20, 2020
eb24e41
style: 💄 remove any
streamich Mar 20, 2020
930b695
feat: 🎸 improve ActionFactoryDefinition
streamich Mar 20, 2020
6a98f45
refactor: 💡 change visualize_embeddable params
streamich Mar 20, 2020
da49052
feat: 🎸 add dashboard dependency to dashboard_enhanced
streamich Mar 20, 2020
baf0f5e
style: 💄 rename drilldown plugin life-cycle contracts
streamich Mar 20, 2020
a5d7a38
refactor: 💡 do naming adjustments for dashboard drilldown
streamich Mar 20, 2020
36fb629
Merge branch 'master' into drilldowns
elasticmachine Mar 20, 2020
e68dcfb
fix: 🐛 fix Type error
streamich Mar 20, 2020
fcecc9a
Merge branch 'master' into drilldowns
elasticmachine Mar 20, 2020
47f1095
fix: 🐛 fix TypeScript type errors
streamich Mar 20, 2020
e678e06
test: 💍 fix test after refactor
streamich Mar 21, 2020
1604ab5
refactor: 💡 rename context -> placeContext in React component
streamich Mar 21, 2020
e14cf4a
Merge branch 'master' into drilldowns
elasticmachine Mar 21, 2020
03b2b37
Merge branch 'master' into drilldowns
elasticmachine Mar 22, 2020
d10aa7b
Merge branch 'master' into drilldowns
elasticmachine Mar 23, 2020
0d076d7
Merge branch 'master' into drilldowns
elasticmachine Mar 23, 2020
0dafa57
chore: 🤖 remove setting from kibana.yml
streamich Mar 23, 2020
29ee51c
refactor: 💡 change return type of getAction as per review
streamich Mar 23, 2020
2b162e8
remove custom css per review
Dosant Mar 23, 2020
de6c6b1
refactor: 💡 rename drilldownCount to eventCount
streamich Mar 23, 2020
88a81e2
style: 💄 remove any
streamich Mar 23, 2020
af3777c
Merge remote-tracking branch 'upstream/drilldowns' into drilldowns
streamich Mar 23, 2020
e29030f
refactor: 💡 change how uiActions are passed to vis embeddable
streamich Mar 23, 2020
78e64d6
Merge branch 'master' into drilldowns
elasticmachine Mar 23, 2020
00c42c4
chore: 🤖 catch up with master
streamich Mar 23, 2020
6cd07c5
style: 💄 remove unused import
streamich Mar 23, 2020
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
1 change: 1 addition & 0 deletions .github/CODEOWNERS
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
# For more info, see https://help.github.com/articles/about-codeowners/

# App
/x-pack/legacy/plugins/dashboard_enhanced/ @elastic/kibana-app
/x-pack/legacy/plugins/lens/ @elastic/kibana-app
/x-pack/legacy/plugins/graph/ @elastic/kibana-app
/src/legacy/server/url_shortening/ @elastic/kibana-app
Expand Down
3 changes: 2 additions & 1 deletion src/dev/storybook/aliases.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,13 @@
*/

export const storybookAliases = {
advanced_ui_actions: 'x-pack/plugins/advanced_ui_actions/scripts/storybook.js',
apm: 'x-pack/legacy/plugins/apm/scripts/storybook.js',
canvas: 'x-pack/legacy/plugins/canvas/scripts/storybook_new.js',
codeeditor: 'src/plugins/kibana_react/public/code_editor/scripts/storybook.ts',
drilldowns: 'x-pack/plugins/drilldowns/scripts/storybook.js',
embeddable: 'src/plugins/embeddable/scripts/storybook.js',
infra: 'x-pack/legacy/plugins/infra/scripts/storybook.js',
siem: 'x-pack/legacy/plugins/siem/scripts/storybook.js',
ui_actions: 'x-pack/plugins/advanced_ui_actions/scripts/storybook.js',
ui_actions: 'src/plugins/ui_actions/scripts/storybook.js',
};
4 changes: 4 additions & 0 deletions src/plugins/embeddable/public/bootstrap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import { Filter } from '../../data/public';
import {
applyFilterTrigger,
contextMenuTrigger,
contextMenuDrilldownsTrigger,
createFilterAction,
panelBadgeTrigger,
selectRangeTrigger,
Expand All @@ -32,6 +33,7 @@ import {
VALUE_CLICK_TRIGGER,
SELECT_RANGE_TRIGGER,
CONTEXT_MENU_TRIGGER,
CONTEXT_MENU_DRILLDOWNS_TRIGGER,
PANEL_BADGE_TRIGGER,
ACTION_ADD_PANEL,
ACTION_CUSTOMIZE_PANEL,
Expand All @@ -51,6 +53,7 @@ declare module '../../ui_actions/public' {
filters: Filter[];
};
[CONTEXT_MENU_TRIGGER]: EmbeddableContext;
[CONTEXT_MENU_DRILLDOWNS_TRIGGER]: EmbeddableContext;
[PANEL_BADGE_TRIGGER]: EmbeddableContext;
}

Expand All @@ -70,6 +73,7 @@ declare module '../../ui_actions/public' {
*/
export const bootstrap = (uiActions: UiActionsSetup) => {
uiActions.registerTrigger(contextMenuTrigger);
uiActions.registerTrigger(contextMenuDrilldownsTrigger);
uiActions.registerTrigger(applyFilterTrigger);
uiActions.registerTrigger(panelBadgeTrigger);
uiActions.registerTrigger(selectRangeTrigger);
Expand Down
1 change: 1 addition & 0 deletions src/plugins/embeddable/public/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ export {
ContainerInput,
ContainerOutput,
CONTEXT_MENU_TRIGGER,
CONTEXT_MENU_DRILLDOWNS_TRIGGER,
contextMenuTrigger,
ACTION_EDIT_PANEL,
EditPanelAction,
Expand Down
14 changes: 11 additions & 3 deletions src/plugins/embeddable/public/lib/panel/embeddable_panel.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ import {
import { inspectorPluginMock } from 'src/plugins/inspector/public/mocks';
import { EuiBadge } from '@elastic/eui';

const actionRegistry = new Map<string, Action<object | undefined | string | number>>();
const actionRegistry = new Map<string, Action>();
const triggerRegistry = new Map<string, Trigger>();
const embeddableFactories = new Map<string, EmbeddableFactory>();
const getEmbeddableFactory: GetEmbeddableFactory = (id: string) => embeddableFactories.get(id);
Expand Down Expand Up @@ -213,13 +213,17 @@ const renderInEditModeAndOpenContextMenu = async (
};

test('HelloWorldContainer in edit mode hides disabledActions', async () => {
const action: Action = {
const action = {
id: 'FOO',
type: 'FOO' as ActionType,
getIconType: () => undefined,
getDisplayName: () => 'foo',
isCompatible: async () => true,
execute: async () => {},
order: 10,
getHref: () => {
return undefined;
},
};
const getActions = () => Promise.resolve([action]);

Expand All @@ -245,13 +249,17 @@ test('HelloWorldContainer in edit mode hides disabledActions', async () => {
});

test('HelloWorldContainer hides disabled badges', async () => {
const action: Action = {
const action = {
id: 'BAR',
type: 'BAR' as ActionType,
getIconType: () => undefined,
getDisplayName: () => 'bar',
isCompatible: async () => true,
execute: async () => {},
order: 10,
getHref: () => {
return undefined;
},
};
const getActions = () => Promise.resolve([action]);

Expand Down
47 changes: 35 additions & 12 deletions src/plugins/embeddable/public/lib/panel/embeddable_panel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,22 @@ import { EuiContextMenuPanelDescriptor, EuiPanel, htmlIdGenerator } from '@elast
import classNames from 'classnames';
import React from 'react';
import { Subscription } from 'rxjs';
import { buildContextMenuForActions, UiActionsService, Action } from '../ui_actions';
import {
buildContextMenuForActions,
UiActionsService,
Action,
contextMenuSeparatorAction,
} from '../ui_actions';
import { CoreStart, OverlayStart } from '../../../../../core/public';
import { toMountPoint } from '../../../../kibana_react/public';

import { Start as InspectorStartContract } from '../inspector';
import { CONTEXT_MENU_TRIGGER, PANEL_BADGE_TRIGGER, EmbeddableContext } from '../triggers';
import {
CONTEXT_MENU_TRIGGER,
CONTEXT_MENU_DRILLDOWNS_TRIGGER,
PANEL_BADGE_TRIGGER,
EmbeddableContext,
} from '../triggers';
import { IEmbeddable } from '../embeddables/i_embeddable';
import { ViewMode, GetEmbeddableFactory, GetEmbeddableFactories } from '../types';

Expand All @@ -37,6 +47,14 @@ import { InspectPanelAction } from './panel_header/panel_actions/inspect_panel_a
import { EditPanelAction } from '../actions';
import { CustomizePanelModal } from './panel_header/panel_actions/customize_title/customize_panel_modal';

const sortByOrderField = (
{ order: orderA }: { order?: number },
{ order: orderB }: { order?: number }
) => (orderB || 0) - (orderA || 0);

const removeById = (disabledActions: string[]) => ({ id }: { id: string }) =>
disabledActions.indexOf(id) === -1;

interface Props {
embeddable: IEmbeddable<any, any>;
getActions: UiActionsService['getTriggerCompatibleActions'];
Expand Down Expand Up @@ -200,13 +218,18 @@ export class EmbeddablePanel extends React.Component<Props, State> {
};

private getActionContextMenuPanel = async () => {
let actions = await this.props.getActions(CONTEXT_MENU_TRIGGER, {
let regularActions = await this.props.getActions(CONTEXT_MENU_TRIGGER, {
embeddable: this.props.embeddable,
});
let drilldownActions = await this.props.getActions(CONTEXT_MENU_DRILLDOWNS_TRIGGER, {
embeddable: this.props.embeddable,
});

const { disabledActions } = this.props.embeddable.getInput();
if (disabledActions) {
actions = actions.filter(action => disabledActions.indexOf(action.id) === -1);
const removeDisabledActions = removeById(disabledActions);
regularActions = regularActions.filter(removeDisabledActions);
drilldownActions = drilldownActions.filter(removeDisabledActions);
}

const createGetUserData = (overlays: OverlayStart) =>
Expand Down Expand Up @@ -245,16 +268,16 @@ export class EmbeddablePanel extends React.Component<Props, State> {
new EditPanelAction(this.props.getEmbeddableFactory),
];

const sorted = actions
.concat(extraActions)
.sort((a: Action<EmbeddableContext>, b: Action<EmbeddableContext>) => {
const bOrder = b.order || 0;
const aOrder = a.order || 0;
return bOrder - aOrder;
});
const sortedRegularActions = [...regularActions, ...extraActions].sort(sortByOrderField);
const sortedDrilldownActions = [...drilldownActions].sort(sortByOrderField);
const actions = [
...sortedDrilldownActions,
...(sortedDrilldownActions.length ? [contextMenuSeparatorAction] : []),
...sortedRegularActions,
];

return await buildContextMenuForActions({
actions: sorted,
actions,
actionContext: { embeddable: this.props.embeddable },
closeMenu: this.closeMyContextMenuPanel,
});
Expand Down
7 changes: 7 additions & 0 deletions src/plugins/embeddable/public/lib/triggers/triggers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,13 @@ export const contextMenuTrigger: Trigger<'CONTEXT_MENU_TRIGGER'> = {
description: 'Triggered on top-right corner context-menu select.',
};

export const CONTEXT_MENU_DRILLDOWNS_TRIGGER = 'CONTEXT_MENU_DRILLDOWNS_TRIGGER';
export const contextMenuDrilldownsTrigger: Trigger<'CONTEXT_MENU_DRILLDOWNS_TRIGGER'> = {
id: CONTEXT_MENU_DRILLDOWNS_TRIGGER,
title: 'Drilldown context menu',
description: 'Triggered on top-right corner context-menu select.',
};

export const APPLY_FILTER_TRIGGER = 'FILTER_TRIGGER';
export const applyFilterTrigger: Trigger<'FILTER_TRIGGER'> = {
id: APPLY_FILTER_TRIGGER,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,58 @@ import { Comparator, Connect, StateContainer, UnboxState } from './types';

const { useContext, useLayoutEffect, useRef, createElement: h } = React;

/**
* Returns the latest state of a state container.
*
* @param container State container which state to track.
*/
export const useContainerState = <Container extends StateContainer<any, any>>(
streamich marked this conversation as resolved.
Show resolved Hide resolved
container: Container
): UnboxState<Container> => useObservable(container.state$, container.get());

/**
* Apply selector to state container to extract only needed information. Will
* re-render your component only when the section changes.
*
* @param container State container which state to track.
* @param selector Function used to pick parts of state.
* @param comparator Comparator function used to memoize previous result, to not
* re-render React component if state did not change. By default uses
* `fast-deep-equal` package.
*/
export const useContainerSelector = <Container extends StateContainer<any, any>, Result>(
container: Container,
selector: (state: UnboxState<Container>) => Result,
comparator: Comparator<Result> = defaultComparator
): Result => {
const { state$, get } = container;
const lastValueRef = useRef<Result>(get());
const [value, setValue] = React.useState<Result>(() => {
const newValue = selector(get());
lastValueRef.current = newValue;
return newValue;
});
useLayoutEffect(() => {
const subscription = state$.subscribe((currentState: UnboxState<Container>) => {
const newValue = selector(currentState);
if (!comparator(lastValueRef.current, newValue)) {
lastValueRef.current = newValue;
setValue(newValue);
}
});
return () => subscription.unsubscribe();
}, [state$, comparator]);
return value;
};

export const createStateContainerReactHelpers = <Container extends StateContainer<any, any>>() => {
const context = React.createContext<Container>(null as any);

const useContainer = (): Container => useContext(context);

const useState = (): UnboxState<Container> => {
const { state$, get } = useContainer();
const value = useObservable(state$, get());
return value;
const container = useContainer();
return useContainerState(container);
};

const useTransitions: () => Container['transitions'] = () => useContainer().transitions;
Expand All @@ -41,24 +84,8 @@ export const createStateContainerReactHelpers = <Container extends StateContaine
selector: (state: UnboxState<Container>) => Result,
comparator: Comparator<Result> = defaultComparator
): Result => {
const { state$, get } = useContainer();
const lastValueRef = useRef<Result>(get());
const [value, setValue] = React.useState<Result>(() => {
const newValue = selector(get());
lastValueRef.current = newValue;
return newValue;
});
useLayoutEffect(() => {
const subscription = state$.subscribe((currentState: UnboxState<Container>) => {
const newValue = selector(currentState);
if (!comparator(lastValueRef.current, newValue)) {
lastValueRef.current = newValue;
setValue(newValue);
}
});
return () => subscription.unsubscribe();
}, [state$, comparator]);
return value;
const container = useContainer();
return useContainerSelector<Container, Result>(container, selector, comparator);
};

const connect: Connect<UnboxState<Container>> = mapStateToProp => component => props =>
Expand Down
48 changes: 47 additions & 1 deletion src/plugins/ui_actions/public/actions/action.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,12 @@

import { UiComponent } from 'src/plugins/kibana_utils/common';
import { ActionType, ActionContextMapping } from '../types';
import { Presentable } from '../util/presentable';

export type ActionByType<T extends ActionType> = Action<ActionContextMapping[T], T>;

export interface Action<Context = {}, T = ActionType> {
export interface Action<Context extends {} = {}, T = ActionType>
extends Partial<Presentable<Context>> {
/**
* Determined the order when there is more than one action matched to a trigger.
* Higher numbers are displayed first.
Expand Down Expand Up @@ -72,3 +74,47 @@ export interface Action<Context = {}, T = ActionType> {
*/
execute(context: Context): Promise<void>;
}

/**
* A convenience interface used to register an action.
*/
export interface ActionDefinition<
Context extends object = object,
Config extends object | undefined = undefined
> extends Partial<Presentable<Context>> {
/**
* ID of the action that uniquely identifies this action in the actions registry.
*/
readonly id: string;

/**
* ID of the factory for this action. Used to construct dynamic actions.
*/
readonly type?: ActionType;

getHref?(context: Context): string | undefined;

/**
* Executes the action.
*/
execute(context: Context): Promise<void>;
}

export type AnyActionDefinition = ActionDefinition<any, any>;
export type ActionContext<A> = A extends ActionDefinition<infer Context, any> ? Context : never;
export type ActionConfig<A> = A extends ActionDefinition<any, infer Config> ? Config : never;

/**
* A convenience interface used to register a dynamic action.
*
* A dynamic action is one that can be create by user and registered into the
* actions registry at runtime. User can also provide custom config for this
* action. And dynamic actions can be serialized for storage and deserialized
* back.
*/
export type DynamicActionDefinition<
Context extends object = object,
Config extends object | undefined = undefined
> = ActionDefinition<Context, Config>;

export type AnyDynamicActionDefinition = DynamicActionDefinition<any, any>;
38 changes: 38 additions & 0 deletions src/plugins/ui_actions/public/actions/action_contract.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

import { ActionInternal } from './action_internal';
import { AnyActionDefinition } from './action';

/**
* Action representation that is exposed out to other plugins.
*/
export type ActionContract<A extends AnyActionDefinition> = Pick<
ActionInternal<A>,
| 'id'
| 'type'
| 'order'
| 'getIconType'
| 'getDisplayName'
| 'isCompatible'
| 'getHref'
| 'execute'
>;

export type AnyActionContract = ActionContract<any>;
Loading