Skip to content

Commit

Permalink
Drilldowns (#59632)
Browse files Browse the repository at this point in the history
* Add drilldown wizard components

* Dynamic actions (#58216)

* feat: 🎸 add DynamicAction and FactoryAction types

* feat: 🎸 add Mutable<T> type to @kbn/utility-types

* feat: 🎸 add ActionInternal and ActionContract

* chore: 🤖 remove unused file

* feat: 🎸 improve action interfaces

* docs: ✏️ add JSDocs

* feat: 🎸 simplify ui_actions interfaces

* fix: 🐛 fix TypeScript types

* feat: 🎸 add AbstractPresentable interface

* feat: 🎸 add AbstractConfigurable interface

* feat: 🎸 use AbstractPresentable in ActionInternal

* test: 💍 fix ui_actions Jest tests

* feat: 🎸 add state container to action

* perf: ⚡️ convert MenuItem to React component on Action instance

* refactor: 💡 rename AbsractPresentable -> Presentable

* refactor: 💡 rename AbstractConfigurable -> Configurable

* feat: 🎸 add Storybook to ui_actions

* feat: 🎸 add <ErrorConfigureAction> component

* feat: 🎸 improve <ConfigureAction> component

* chore: 🤖 use .story file extension prefix for Storybook

* feat: 🎸 improve <ErrorConfigureAction> component

* feat: 🎸 show error if dynamic action has CollectConfig missing

* feat: 🎸 render sample action configuration component

* feat: 🎸 connect action config to <ConfigureAction>

* feat: 🎸 improve <ConfigureAction> stories

* test: 💍 add ActionInternal serialize/deserialize tests

* feat: 🎸 add ActionContract

* feat: 🎸 split action Context into Execution and Presentation

* fix: 🐛 fix TypeScript error

* refactor: 💡 extract state container hooks to module scope

* docs: ✏️ fix typos

* chore: 🤖 remove Mutable<t> type

* test: 💍 don't cast to any getActions() function

* style: 💄 avoid using unnecessary types

* chore: 🤖 address PR review comments

* chore: 🤖 rename ActionContext generic

* chore: 🤖 remove order from state container

* chore: 🤖 remove deprecation notice on getHref

* test: 💍 fix tests after order field change

* remove comments

Co-authored-by: Matt Kime <matt@mattki.me>
Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>

* Drilldown context menu (#59638)

* fix: 🐛 fix TypeScript error

* feat: 🎸 add CONTEXT_MENU_DRILLDOWNS_TRIGGER trigger

* fix: 🐛 correctly order context menu items

* fix: 🐛 set correct order on drilldown flyout actions

* fix: 🐛 clean up context menu building functions

* feat: 🎸 add context menu separator action

* Add basic ActionFactoryService. Pass data from it into components instead of mocks

* Dashboard x pack (#59653)

* feat: 🎸 add dashboard_enhanced plugin to x-pack

* feat: 🎸 improve context menu separator

* feat: 🎸 move drilldown flyout actions to dashboard_enhanced

* fix: 🐛 fix exports from ui_actions plugin

* feat: 🎸 "implement" registerDrilldown() method

* fix ConfigurableBaseConfig type

* Implement connected flyout_manage_drilldowns component

* Simplify connected flyout manage drilldowns component. Remove intermediate component

* clean up data-testid workaround in new components

* Connect welcome message to storage

Not sure, but use LocalStorage. Didn’t find a way to persist user settings. looks like uiSettings are not user scoped.

* require `context` in Presentable. drill context down through wizard components

* Drilldown factory (#59823)

* refactor: 💡 import storage interface from ui_actions plugin

* refactor: 💡 make actions not-dynamic

* feat: 🎸 fix TypeScript errors, reshuffle types and code

* fix: 🐛 fix more TypeScript errors

* fix: 🐛 fix TypeScript import error

* Drilldown registration (#59834)

* feat: 🎸 improve drilldown registration method

* fix: 🐛 set up translations for dashboard_enhanced plugin

* Drilldown events 3 (#59854)

* feat: 🎸 add serialize/unserialize to action

* feat: 🎸 pass in uiActions service into Embeddable

* feat: 🎸 merge ui_actions oss and basic plugins

* refactor: 💡 move action factory registry to OSS

* fix: 🐛 fix TypeScript errors

* Drilldown events 4 (#59876)

* feat: 🎸 mock sample drilldown execute methods

* feat: 🎸 add .dynamicActions manager to Embeddable

* feat: 🎸 add first version of dynamic action manager

* Drilldown events 5 (#59885)

* feat: 🎸 display drilldowns in context menu only on one embed

* feat: 🎸 clear dynamic actions from registry when embed unloads

* fix: 🐛 fix OSS TypeScript errors

* basic integration of components with dynamicActionManager

* fix: 🐛 don't overwrite explicitInput with combined input (#59938)

* display drilldown count in embeddable edit mode

* display drilldown count in embeddable edit mode

* improve wizard components. more tests.

* partial progress, dashboard drilldowns (#59977)

* partial progress, dashboard drilldowns

* partial progress, dashboard drilldowns

* feat: 🎸 improve dashboard drilldown setup

* feat: 🎸 wire in services into dashboard drilldown

* chore: 🤖 add Storybook to dashboard_enhanced

* feat: 🎸 create presentational <DashboardDrilldownConfig>

* test: 💍 add <DashboardDrilldownConfig> stories

* test: 💍 use presentation dashboar config component

* feat: 🎸 wire in services into React component

* docs: ✏️ add README to /components folder

* feat: 🎸 increase importance of Dashboard drilldown

* feat: 🎸 improve icon definition in drilldowns

* chore: 🤖 remove unnecessary comment

* chore: 🤖 add todos

Co-authored-by: streamich <streamich@gmail.com>

* Manage drilldowns toasts. Add basic error handling.

* support order in action factory selector

* fix column order in manage drilldowns list

* remove accidental debug info

* bunch of nit ui fixes

* Drilldowns reactive action manager (#60099)

* feat: 🎸 improve isConfigValid return type

* feat: 🎸 make DynamicActionManager reactive

* docs: ✏️ add JSDocs to public mehtods of DynamicActionManager

* feat: 🎸 make panel top-right corner number badge reactive

* fix: 🐛 correctly await for .deleteEvents()

* Drilldowns various 2 (#60103)

* chore: 🤖 address review comments

* test: 💍 fix embeddable_panel.test.tsx tests

* chore: 🤖 clean up ActionInternal

* chore: 🤖 make isConfigValid a simple predicate

* chore: 🤖 fix TypeScript type errors

* test: 💍 stub DynamicActionManager tests (#60104)

* Drilldowns review 1 (#60139)

* refactor: 💡 improve generic types

* fix: 🐛 don't overwrite icon

* fix: 🐛 fix x-pack TypeScript errors

* fix: 🐛 fix TypeScript error

* fix: 🐛 correct merge

* Drilldowns various 4 (#60264)

* feat: 🎸 hide "Create drilldown" from context menu when needed

* style: 💄 remove AnyDrilldown type

* feat: 🎸 add drilldown factory context

* chore: 🤖 remove sample drilldown

* fix: 🐛 increase spacing between action factory picker

* workaround issue with closing flyout when navigating away

Adds overlay just like other flyouts which makes this defect harder to bump in

* fix react key issue in action_wizard

* don’t open 2 flyouts

* fix action order

#60138

* Drilldowns reload stored (#60336)

* style: 💄 don't use double equals __

* feat: 🎸 add reload$ to ActionStorage interface

* feat: 🎸 add reload$ to embeddable event storage

* feat: 🎸 add storage syncing to DynamicActionManager

* refactor: 💡 use state from DynamicActionManager in React

* fix: 🐛 add check for manager being stopped

* Drilldowns triggers (#60339)

* feat: 🎸 make use of supportedTriggers()

* feat: 🎸 pass in context to configuration component

* feat: 🎸 augment factory context

* fix: 🐛 stop infinite re-rendering

* Drilldowns multitrigger (#60357)

* feat: 🎸 add support for multiple triggers

* feat: 🎸 enable Drilldowns for TSVB

Although TSVB brushing event is now broken on master, KibanaApp plans to
fix it in 7.7

* "Create drilldown" flyout - design cleanup (#60309)

* create drilldown flyout cleanup

* remove border from selectedActionFactoryContainer

* adjust callout in DrilldownHello

* update form labels

* remove unused file

* fix type error

Co-authored-by: Anton Dosov <anton.dosov@elastic.co>

* basic unit tests for flyout_create_drildown action

* Drilldowns finalize (#60371)

* fix: 🐛 align flyout content to left side

* fix: 🐛 move context menu item number 1px lower

* fix: 🐛 move flyout back nav chevron up

* fix: 🐛 fix type check after refactor

* basic unit tests for drilldown actions

* Drilldowns finalize 2 (#60510)

* test: 💍 fix test mock

* chore: 🤖 remove unused UiActionsService methods

* refactor: 💡 cleanup UiActionsService action registration

* fix: 🐛 add missing functionality after refactor

* test: 💍 add action factory tests

* test: 💍 add DynamicActionManager tests

* feat: 🎸 capture error if it happens during initial load

* fix: 🐛 register correctly CSV action

* feat: 🎸 don't show "OPTIONS" title on drilldown context menus

* feat: 🎸 add server-side for x-pack dashboard plugin

* feat: 🎸 disable Drilldowns for TSVB

* feat: 🎸 enable drilldowns on kibana.yml feature flag

* feat: 🎸 add feature flag comment to kibana.yml

* feat: 🎸 remove places from drilldown interface

* refactor: 💡 remove place in factory context

* chore: 🤖 remove doExecute

* remove not needed now error_configure_action component

* remove workaround for storybook

* feat: 🎸 improve DrilldownDefinition interface

* style: 💄 replace any by unknown

* chore: 🤖 remove any

* chore: 🤖 make isConfigValid return type a boolean

* refactor: 💡 move getDisplayName to factory, remove deprecated

* style: 💄 remove any

* feat: 🎸 improve ActionFactoryDefinition

* refactor: 💡 change visualize_embeddable params

* feat: 🎸 add dashboard dependency to dashboard_enhanced

* style: 💄 rename drilldown plugin life-cycle contracts

* refactor: 💡 do naming adjustments for dashboard drilldown

* fix: 🐛 fix Type error

* fix: 🐛 fix TypeScript type errors

* test: 💍 fix test after refactor

* refactor: 💡 rename context -> placeContext in React component

* chore: 🤖 remove setting from kibana.yml

* refactor: 💡 change return type of getAction as per review

* remove custom css per review

* refactor: 💡 rename drilldownCount to eventCount

* style: 💄 remove any

* refactor: 💡 change how uiActions are passed to vis embeddable

* style: 💄 remove unused import

Co-authored-by: Anton Dosov <anton.dosov@elastic.co>
Co-authored-by: Matt Kime <matt@mattki.me>
Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>
Co-authored-by: Andrea Del Rio <delrio.andre@gmail.com>
  • Loading branch information
5 people authored Mar 24, 2020
1 parent e96ed69 commit 5abb2c8
Show file tree
Hide file tree
Showing 164 changed files with 5,368 additions and 898 deletions.
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
2 changes: 1 addition & 1 deletion examples/ui_action_examples/public/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ export class UiActionExamplesPlugin
}));

uiActions.registerAction(helloWorldAction);
uiActions.attachAction(helloWorldTrigger.id, helloWorldAction);
uiActions.addTriggerAction(helloWorldTrigger.id, helloWorldAction);
}

public start() {}
Expand Down
3 changes: 1 addition & 2 deletions examples/ui_actions_explorer/public/app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -95,8 +95,7 @@ const ActionsExplorer = ({ uiActionsApi, openModal }: Props) => {
);
},
});
uiActionsApi.registerAction(dynamicAction);
uiActionsApi.attachAction(HELLO_WORLD_TRIGGER_ID, dynamicAction);
uiActionsApi.addTriggerAction(HELLO_WORLD_TRIGGER_ID, dynamicAction);
setConfirmationText(
`You've successfully added a new action: ${dynamicAction.getDisplayName(
{}
Expand Down
16 changes: 8 additions & 8 deletions examples/ui_actions_explorer/public/plugin.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -79,21 +79,21 @@ export class UiActionsExplorerPlugin implements Plugin<void, void, {}, StartDeps

const startServices = core.getStartServices();

deps.uiActions.attachAction(
deps.uiActions.addTriggerAction(
USER_TRIGGER,
createPhoneUserAction(async () => (await startServices)[1].uiActions)
);
deps.uiActions.attachAction(
deps.uiActions.addTriggerAction(
USER_TRIGGER,
createEditUserAction(async () => (await startServices)[0].overlays.openModal)
);

deps.uiActions.attachAction(COUNTRY_TRIGGER, viewInMapsAction);
deps.uiActions.attachAction(COUNTRY_TRIGGER, lookUpWeatherAction);
deps.uiActions.attachAction(COUNTRY_TRIGGER, showcasePluggability);
deps.uiActions.attachAction(PHONE_TRIGGER, makePhoneCallAction);
deps.uiActions.attachAction(PHONE_TRIGGER, showcasePluggability);
deps.uiActions.attachAction(USER_TRIGGER, showcasePluggability);
deps.uiActions.addTriggerAction(COUNTRY_TRIGGER, viewInMapsAction);
deps.uiActions.addTriggerAction(COUNTRY_TRIGGER, lookUpWeatherAction);
deps.uiActions.addTriggerAction(COUNTRY_TRIGGER, showcasePluggability);
deps.uiActions.addTriggerAction(PHONE_TRIGGER, makePhoneCallAction);
deps.uiActions.addTriggerAction(PHONE_TRIGGER, showcasePluggability);
deps.uiActions.addTriggerAction(USER_TRIGGER, showcasePluggability);

core.application.register({
id: 'uiActionsExplorer',
Expand Down
1 change: 1 addition & 0 deletions src/core/public/overlays/flyout/flyout_service.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ export interface OverlayFlyoutStart {
export interface OverlayFlyoutOpenOptions {
className?: string;
closeButtonAriaLabel?: string;
ownFocus?: boolean;
'data-test-subj'?: string;
}

Expand Down
4 changes: 3 additions & 1 deletion src/dev/storybook/aliases.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,14 @@
*/

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',
dashboard_enhanced: 'x-pack/plugins/dashboard_enhanced/scripts/storybook.js',
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',
};
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ import { PersistedState } from '../../../../../../../plugins/visualizations/publ
import { buildPipeline } from '../legacy/build_pipeline';
import { Vis } from '../vis';
import { getExpressions, getUiActions } from '../services';
import { VisualizationsStartDeps } from '../plugin';
import { VIS_EVENT_TO_TRIGGER } from './events';

const getKeys = <T extends {}>(o: T): Array<keyof T> => Object.keys(o) as Array<keyof T>;
Expand All @@ -56,6 +57,7 @@ export interface VisualizeEmbeddableConfiguration {
editable: boolean;
appState?: { save(): void };
uiState?: PersistedState;
uiActions?: VisualizationsStartDeps['uiActions'];
}

export interface VisualizeInput extends EmbeddableInput {
Expand Down Expand Up @@ -94,7 +96,7 @@ export class VisualizeEmbeddable extends Embeddable<VisualizeInput, VisualizeOut

constructor(
timefilter: TimefilterContract,
{ vis, editUrl, indexPatterns, editable }: VisualizeEmbeddableConfiguration,
{ vis, editUrl, indexPatterns, editable, uiActions }: VisualizeEmbeddableConfiguration,
initialInput: VisualizeInput,
parent?: Container
) {
Expand All @@ -107,7 +109,8 @@ export class VisualizeEmbeddable extends Embeddable<VisualizeInput, VisualizeOut
editable,
visTypeName: vis.type.name,
},
parent
parent,
{ uiActions }
);
this.timefilter = timefilter;
this.vis = vis;
Expand Down Expand Up @@ -265,6 +268,7 @@ export class VisualizeEmbeddable extends Embeddable<VisualizeInput, VisualizeOut
timeFieldName: this.vis.data.indexPattern!.timeFieldName!,
data: event.data,
};

getUiActions()
.getTrigger(triggerId)
.exec(context);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ import {
getTimeFilter,
} from '../services';
import { showNewVisModal } from '../wizard';
import { VisualizationsStartDeps } from '../plugin';
import { convertToSerializedVis } from '../saved_visualizations/_saved_vis';

interface VisualizationAttributes extends SavedObjectAttributes {
Expand All @@ -52,7 +53,11 @@ export class VisualizeEmbeddableFactory extends EmbeddableFactory<
> {
public readonly type = VISUALIZE_EMBEDDABLE_TYPE;

constructor() {
constructor(
private readonly getUiActions: () => Promise<
Pick<VisualizationsStartDeps, 'uiActions'>['uiActions']
>
) {
super({
savedObjectMetaData: {
name: i18n.translate('visualizations.savedObjectName', { defaultMessage: 'Visualization' }),
Expand Down Expand Up @@ -114,6 +119,8 @@ export class VisualizeEmbeddableFactory extends EmbeddableFactory<

const indexPattern = vis.data.indexPattern;
const indexPatterns = indexPattern ? [indexPattern] : [];
const uiActions = await this.getUiActions();

const editable = await this.isEditable();
return new VisualizeEmbeddable(
getTimeFilter(),
Expand All @@ -124,6 +131,7 @@ export class VisualizeEmbeddableFactory extends EmbeddableFactory<
editable,
appState: input.appState,
uiState: input.uiState,
uiActions,
},
input,
parent
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
* under the License.
*/

import { PluginInitializerContext } from '../../../../../../core/public';
import { CoreSetup, PluginInitializerContext } from '../../../../../../core/public';
import { VisualizationsSetup, VisualizationsStart } from './';
import { VisualizationsPlugin } from './plugin';
import { coreMock } from '../../../../../../core/public/mocks';
Expand All @@ -26,6 +26,7 @@ import { expressionsPluginMock } from '../../../../../../plugins/expressions/pub
import { dataPluginMock } from '../../../../../../plugins/data/public/mocks';
import { usageCollectionPluginMock } from '../../../../../../plugins/usage_collection/public/mocks';
import { uiActionsPluginMock } from '../../../../../../plugins/ui_actions/public/mocks';
import { VisualizationsStartDeps } from './plugin';

const createSetupContract = (): VisualizationsSetup => ({
createBaseVisualization: jest.fn(),
Expand All @@ -48,7 +49,7 @@ const createStartContract = (): VisualizationsStart => ({
const createInstance = async () => {
const plugin = new VisualizationsPlugin({} as PluginInitializerContext);

const setup = plugin.setup(coreMock.createSetup(), {
const setup = plugin.setup(coreMock.createSetup() as CoreSetup<VisualizationsStartDeps>, {
data: dataPluginMock.createSetupContract(),
expressions: expressionsPluginMock.createSetupContract(),
embeddable: embeddablePluginMock.createSetupContract(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ export class VisualizationsPlugin
constructor(initializerContext: PluginInitializerContext) {}

public setup(
core: CoreSetup,
core: CoreSetup<VisualizationsStartDeps>,
{ expressions, embeddable, usageCollection, data }: VisualizationsSetupDeps
): VisualizationsSetup {
setUISettings(core.uiSettings);
Expand All @@ -120,7 +120,9 @@ export class VisualizationsPlugin
expressions.registerFunction(visualizationFunction);
expressions.registerRenderer(visualizationRenderer);

const embeddableFactory = new VisualizeEmbeddableFactory();
const embeddableFactory = new VisualizeEmbeddableFactory(
async () => (await core.getStartServices())[1].uiActions
);
embeddable.registerEmbeddableFactory(VISUALIZE_EMBEDDABLE_TYPE, embeddableFactory);

return {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ export interface ReplacePanelActionContext {
export class ReplacePanelAction implements ActionByType<typeof ACTION_REPLACE_PANEL> {
public readonly type = ACTION_REPLACE_PANEL;
public readonly id = ACTION_REPLACE_PANEL;
public order = 11;
public order = 3;

constructor(
private core: CoreStart,
Expand Down
4 changes: 2 additions & 2 deletions src/plugins/dashboard/public/plugin.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ export class DashboardEmbeddableContainerPublicPlugin
): Setup {
const expandPanelAction = new ExpandPanelAction();
uiActions.registerAction(expandPanelAction);
uiActions.attachAction(CONTEXT_MENU_TRIGGER, expandPanelAction);
uiActions.attachAction(CONTEXT_MENU_TRIGGER, expandPanelAction.id);
const startServices = core.getStartServices();

if (share) {
Expand Down Expand Up @@ -134,7 +134,7 @@ export class DashboardEmbeddableContainerPublicPlugin
plugins.embeddable.getEmbeddableFactories
);
uiActions.registerAction(changeViewAction);
uiActions.attachAction(CONTEXT_MENU_TRIGGER, changeViewAction);
uiActions.addTriggerAction(CONTEXT_MENU_TRIGGER, changeViewAction);
}

public stop() {}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ test('DashboardContainer in edit mode shows edit mode actions', async () => {

const editModeAction = createEditModeAction();
uiActionsSetup.registerAction(editModeAction);
uiActionsSetup.attachAction(CONTEXT_MENU_TRIGGER, editModeAction);
uiActionsSetup.addTriggerAction(CONTEXT_MENU_TRIGGER, editModeAction);
setup.registerEmbeddableFactory(
CONTACT_CARD_EMBEDDABLE,
new ContactCardEmbeddableFactory({} as any, (() => null) as any, {} as any)
Expand Down
9 changes: 6 additions & 3 deletions src/plugins/data/public/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -109,12 +109,12 @@ export class DataPublicPlugin implements Plugin<DataPublicPluginSetup, DataPubli
createFilterAction(queryService.filterManager, queryService.timefilter.timefilter)
);

uiActions.attachAction(
uiActions.addTriggerAction(
SELECT_RANGE_TRIGGER,
selectRangeAction(queryService.filterManager, queryService.timefilter.timefilter)
);

uiActions.attachAction(
uiActions.addTriggerAction(
VALUE_CLICK_TRIGGER,
valueClickAction(queryService.filterManager, queryService.timefilter.timefilter)
);
Expand Down Expand Up @@ -146,7 +146,10 @@ export class DataPublicPlugin implements Plugin<DataPublicPluginSetup, DataPubli
const search = this.searchService.start(core);
setSearchService(search);

uiActions.attachAction(APPLY_FILTER_TRIGGER, uiActions.getAction(ACTION_GLOBAL_APPLY_FILTER));
uiActions.addTriggerAction(
APPLY_FILTER_TRIGGER,
uiActions.getAction(ACTION_GLOBAL_APPLY_FILTER)
);

const dataServices = {
actions: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ interface ActionContext {
export class EditPanelAction implements Action<ActionContext> {
public readonly type = ACTION_EDIT_PANEL;
public readonly id = ACTION_EDIT_PANEL;
public order = 15;
public order = 50;

constructor(private readonly getEmbeddableFactory: EmbeddableStart['getEmbeddableFactory']) {}

Expand Down
73 changes: 65 additions & 8 deletions src/plugins/embeddable/public/lib/embeddables/embeddable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,23 +16,35 @@
* specific language governing permissions and limitations
* under the License.
*/
import { isEqual, cloneDeep } from 'lodash';
import { cloneDeep, isEqual } from 'lodash';
import * as Rx from 'rxjs';
import { Adapters } from '../types';
import { Adapters, ViewMode } from '../types';
import { IContainer } from '../containers';
import { IEmbeddable, EmbeddableInput, EmbeddableOutput } from './i_embeddable';
import { ViewMode } from '../types';
import { EmbeddableInput, EmbeddableOutput, IEmbeddable } from './i_embeddable';
import { TriggerContextMapping } from '../ui_actions';
import { EmbeddableActionStorage } from './embeddable_action_storage';
import {
UiActionsDynamicActionManager,
UiActionsStart,
} from '../../../../../plugins/ui_actions/public';
import { EmbeddableContext } from '../triggers';

function getPanelTitle(input: EmbeddableInput, output: EmbeddableOutput) {
return input.hidePanelTitles ? '' : input.title === undefined ? output.defaultTitle : input.title;
}

export interface EmbeddableParams {
uiActions?: UiActionsStart;
}

export abstract class Embeddable<
TEmbeddableInput extends EmbeddableInput = EmbeddableInput,
TEmbeddableOutput extends EmbeddableOutput = EmbeddableOutput
> implements IEmbeddable<TEmbeddableInput, TEmbeddableOutput> {
static runtimeId: number = 0;

public readonly runtimeId = Embeddable.runtimeId++;

public readonly parent?: IContainer;
public readonly isContainer: boolean = false;
public abstract readonly type: string;
Expand All @@ -48,15 +60,34 @@ export abstract class Embeddable<
// to update input when the parent changes.
private parentSubscription?: Rx.Subscription;

private storageSubscription?: Rx.Subscription;

// TODO: Rename to destroyed.
private destoyed: boolean = false;

private __actionStorage?: EmbeddableActionStorage;
public get actionStorage(): EmbeddableActionStorage {
return this.__actionStorage || (this.__actionStorage = new EmbeddableActionStorage(this));
private storage = new EmbeddableActionStorage((this as unknown) as Embeddable);

private cachedDynamicActions?: UiActionsDynamicActionManager;
public get dynamicActions(): UiActionsDynamicActionManager | undefined {
if (!this.params.uiActions) return undefined;
if (!this.cachedDynamicActions) {
this.cachedDynamicActions = new UiActionsDynamicActionManager({
isCompatible: async (context: unknown) =>
(context as EmbeddableContext).embeddable.runtimeId === this.runtimeId,
storage: this.storage,
uiActions: this.params.uiActions,
});
}

return this.cachedDynamicActions;
}

constructor(input: TEmbeddableInput, output: TEmbeddableOutput, parent?: IContainer) {
constructor(
input: TEmbeddableInput,
output: TEmbeddableOutput,
parent?: IContainer,
public readonly params: EmbeddableParams = {}
) {
this.id = input.id;
this.output = {
title: getPanelTitle(input, output),
Expand All @@ -80,6 +111,18 @@ export abstract class Embeddable<
this.onResetInput(newInput);
});
}

if (this.dynamicActions) {
this.dynamicActions.start().catch(error => {
/* eslint-disable */
console.log('Failed to start embeddable dynamic actions', this);
console.error(error);
/* eslint-enable */
});
this.storageSubscription = this.input$.subscribe(() => {
this.storage.reload$.next();
});
}
}

public getIsContainer(): this is IContainer {
Expand Down Expand Up @@ -158,6 +201,20 @@ export abstract class Embeddable<
*/
public destroy(): void {
this.destoyed = true;

if (this.dynamicActions) {
this.dynamicActions.stop().catch(error => {
/* eslint-disable */
console.log('Failed to stop embeddable dynamic actions', this);
console.error(error);
/* eslint-enable */
});
}

if (this.storageSubscription) {
this.storageSubscription.unsubscribe();
}

if (this.parentSubscription) {
this.parentSubscription.unsubscribe();
}
Expand Down
Loading

0 comments on commit 5abb2c8

Please sign in to comment.