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 review 1 #60139

Merged
merged 4 commits into from
Mar 13, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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: 0 additions & 1 deletion src/plugins/ui_actions/public/actions/action.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,5 +91,4 @@ export interface ActionDefinition<Context extends object = object>
execute(context: Context): Promise<void>;
}

export type AnyActionDefinition = ActionDefinition<any>;
export type ActionContext<A> = A extends ActionDefinition<infer Context> ? Context : never;
62 changes: 30 additions & 32 deletions src/plugins/ui_actions/public/actions/action_factory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,54 +20,52 @@
import { uiToReactComponent } from '../../../kibana_react/public';
import { Presentable } from '../util/presentable';
import { ActionDefinition } from './action';
import {
AnyActionFactoryDefinition,
AFDConfig as Config,
AFDFactoryContext as FactoryContext,
AFDActionContext as ActionContext,
} from './action_factory_definition';
import { ActionFactoryDefinition } from './action_factory_definition';
import { Configurable } from '../util';
import { SerializedAction } from './types';

export class ActionFactory<D extends AnyActionFactoryDefinition>
implements Presentable<FactoryContext<D>>, Configurable<Config<D>> {
constructor(public readonly definition: D) {}
export class ActionFactory<
Config extends object = object,
FactoryContext extends object = object,
ActionContext extends object = object
> implements Presentable<FactoryContext>, Configurable<Config> {
constructor(
protected readonly def: ActionFactoryDefinition<Config, FactoryContext, ActionContext>
) {}

public readonly id = this.definition.id;
public readonly order = this.definition.order || 0;
public readonly MenuItem? = this.definition.MenuItem;
public readonly id = this.def.id;
public readonly order = this.def.order || 0;
public readonly MenuItem? = this.def.MenuItem;
public readonly ReactMenuItem? = this.MenuItem ? uiToReactComponent(this.MenuItem) : undefined;

public readonly CollectConfig = this.definition.CollectConfig;
public readonly CollectConfig = this.def.CollectConfig;
public readonly ReactCollectConfig = uiToReactComponent(this.CollectConfig);
public readonly createConfig = this.definition.createConfig;
public readonly isConfigValid = this.definition.isConfigValid;
public readonly createConfig = this.def.createConfig;
public readonly isConfigValid = this.def.isConfigValid;

public getIconType(context: FactoryContext<D>): string | undefined {
if (!this.definition.getIconType) return undefined;
return this.definition.getIconType(context);
public getIconType(context: FactoryContext): string | undefined {
if (!this.def.getIconType) return undefined;
return this.def.getIconType(context);
}

public getDisplayName(context: FactoryContext<D>): string {
if (!this.definition.getDisplayName) return '';
return this.definition.getDisplayName(context);
public getDisplayName(context: FactoryContext): string {
if (!this.def.getDisplayName) return '';
return this.def.getDisplayName(context);
}

public async isCompatible(context: FactoryContext<D>): Promise<boolean> {
if (!this.definition.isCompatible) return true;
return await this.definition.isCompatible(context);
public async isCompatible(context: FactoryContext): Promise<boolean> {
if (!this.def.isCompatible) return true;
return await this.def.isCompatible(context);
}

public getHref(context: FactoryContext<D>): string | undefined {
if (!this.definition.getHref) return undefined;
return this.definition.getHref(context);
public getHref(context: FactoryContext): string | undefined {
if (!this.def.getHref) return undefined;
return this.def.getHref(context);
}

public create(
serializedAction: Omit<SerializedAction<Config<D>>, 'factoryId'>
): ActionDefinition<ActionContext<D>> {
return this.definition.create(serializedAction);
serializedAction: Omit<SerializedAction<Config>, 'factoryId'>
): ActionDefinition<ActionContext> {
return this.def.create(serializedAction);
}
}

export type AnyActionFactory = ActionFactory<any>;
14 changes: 0 additions & 14 deletions src/plugins/ui_actions/public/actions/action_factory_definition.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,17 +44,3 @@ export interface ActionFactoryDefinition<
serializedAction: Omit<SerializedAction<Config>, 'factoryId'>
): ActionDefinition<ActionContext>;
}

export type AnyActionFactoryDefinition = ActionFactoryDefinition<any, any, any>;

export type AFDConfig<T> = T extends ActionFactoryDefinition<infer Config, any, any>
? Config
: never;

export type AFDFactoryContext<T> = T extends ActionFactoryDefinition<any, infer FactoryContext, any>
? FactoryContext
: never;

export type AFDActionContext<T> = T extends ActionFactoryDefinition<any, any, infer ActionContext>
? ActionContext
: never;
6 changes: 2 additions & 4 deletions src/plugins/ui_actions/public/actions/action_internal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,12 @@
* under the License.
*/

import { Action, ActionContext as Context, AnyActionDefinition } from './action';
import { Action, ActionContext as Context, ActionDefinition } from './action';
import { Presentable } from '../util/presentable';
import { uiToReactComponent } from '../../../kibana_react/public';
import { ActionType } from '../types';

export class ActionInternal<A extends AnyActionDefinition>
export class ActionInternal<A extends ActionDefinition = ActionDefinition>
implements Action<Context<A>>, Presentable<Context<A>> {
constructor(public readonly definition: A) {}

Expand Down Expand Up @@ -56,5 +56,3 @@ export class ActionInternal<A extends AnyActionDefinition>
return this.definition.getHref(context);
}
}

export type AnyActionInternal = ActionInternal<any>;
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,6 @@ export class DynamicActionManager {
id: actionId,
isCompatible,
getDisplayName: () => name,
getIconType: context => factory.getIconType(context),
};

uiActions.addTriggerAction(triggerId as any, actionDefinition);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,10 @@

import React from 'react';
import { EuiCode } from '@elastic/eui';
import { AnyActionInternal } from '../../actions';
import { ActionInternal } from '../../actions';

export interface ActionIdentifierProps {
action: AnyActionInternal;
action: ActionInternal;
}

export const ActionIdentifier: React.FC<ActionIdentifierProps> = ({ action }) => (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,12 @@
import React from 'react';
import { EuiCallOut } from '@elastic/eui';
import { txtSorryActionConfigurationError } from './i18n';
import { AnyActionInternal } from '../../actions';
import { ActionIdentifier } from './action_identifier';
import { ActionInternal } from '../../actions';

export interface ErrorConfigureActionProps {
msg?: React.ReactNode;
action?: AnyActionInternal;
action?: ActionInternal;
}

export const ErrorConfigureAction: React.FC<ErrorConfigureActionProps> = ({
Expand Down
17 changes: 7 additions & 10 deletions src/plugins/ui_actions/public/service/ui_actions_service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,11 @@ import {
} from '../types';
import {
ActionInternal,
AnyActionInternal,
Action,
ActionByType,
AnyActionDefinition,
AnyActionFactoryDefinition,
ActionFactory,
AnyActionFactory,
ActionDefinition,
ActionFactoryDefinition,
} from '../actions';
import { Trigger, TriggerContext } from '../triggers/trigger';
import { TriggerInternal } from '../triggers/trigger_internal';
Expand Down Expand Up @@ -91,7 +88,7 @@ export class UiActionsService {
return trigger.contract;
};

public readonly registerAction = <A extends AnyActionDefinition>(
public readonly registerAction = <A extends ActionDefinition>(
definition: A
): ActionInternal<A> => {
if (this.actions.has(definition.id)) {
Expand Down Expand Up @@ -147,7 +144,7 @@ export class UiActionsService {
}
};

public readonly getAction = <T extends AnyActionDefinition>(id: string): ActionInternal<T> => {
public readonly getAction = <T extends ActionDefinition>(id: string): ActionInternal<T> => {
if (!this.actions.has(id)) {
throw new Error(`Action [action.id = ${id}] not registered.`);
}
Expand Down Expand Up @@ -212,7 +209,7 @@ export class UiActionsService {
const actionIds = this.triggerToActions.get(triggerId);

const actions = actionIds!
.map(actionId => this.actions.get(actionId) as AnyActionInternal)
.map(actionId => this.actions.get(actionId) as ActionInternal)
.filter(Boolean);

return actions as Array<Action<TriggerContext<T>>>;
Expand Down Expand Up @@ -276,7 +273,7 @@ export class UiActionsService {
* Register an action factory. Action factories are used to configure and
* serialize/deserialize dynamic actions.
*/
public readonly registerActionFactory = (definition: AnyActionFactoryDefinition) => {
public readonly registerActionFactory = (definition: ActionFactoryDefinition) => {
if (this.actionFactories.has(definition.id)) {
throw new Error(`ActionFactory [actionFactory.id = ${definition.id}] already registered.`);
}
Expand All @@ -286,7 +283,7 @@ export class UiActionsService {
this.actionFactories.set(actionFactory.id, actionFactory);
};

public readonly getActionFactory = (actionFactoryId: string): AnyActionFactory => {
public readonly getActionFactory = (actionFactoryId: string): ActionFactory => {
const actionFactory = this.actionFactories.get(actionFactoryId);

if (!actionFactory) {
Expand All @@ -299,7 +296,7 @@ export class UiActionsService {
/**
* Returns an array of all action factories.
*/
public readonly getActionFactories = (): AnyActionFactory[] => {
public readonly getActionFactories = (): ActionFactory[] => {
return [...this.actionFactories.values()];
};
}
6 changes: 3 additions & 3 deletions src/plugins/ui_actions/public/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,12 @@

import { ActionInternal } from './actions/action_internal';
import { TriggerInternal } from './triggers/trigger_internal';
import { AnyActionFactory } from './actions/action_factory';
import { ActionFactory } from './actions';

export type TriggerRegistry = Map<TriggerId, TriggerInternal<any>>;
export type ActionRegistry = Map<string, ActionInternal<any>>;
export type ActionRegistry = Map<string, ActionInternal>;
export type TriggerToActionsRegistry = Map<TriggerId, string[]>;
export type ActionFactoryRegistry = Map<string, AnyActionFactory>;
export type ActionFactoryRegistry = Map<string, ActionFactory>;

const DEFAULT_TRIGGER = '';

Expand Down
10 changes: 3 additions & 7 deletions src/plugins/ui_actions/public/util/configurable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,10 @@

import { UiComponent } from 'src/plugins/kibana_utils/common';

export type ConfigurableBaseConfig = object;

/**
* Represents something that can be configured by user using UI.
*/
export interface Configurable<Config extends ConfigurableBaseConfig = ConfigurableBaseConfig> {
export interface Configurable<Config extends object = object> {
/**
* Create default config for this item, used when item is created for the first time.
*/
Expand All @@ -33,7 +31,7 @@ export interface Configurable<Config extends ConfigurableBaseConfig = Configurab
/**
* Is this config valid. Used to validate user's input before saving.
*/
readonly isConfigValid: (config: Config) => boolean;
readonly isConfigValid: (config: Config) => config is Config;

/**
* `UiComponent` to be rendered when collecting configuration for this item.
Expand All @@ -44,9 +42,7 @@ export interface Configurable<Config extends ConfigurableBaseConfig = Configurab
/**
* Props provided to `CollectConfig` component on every re-render.
*/
export interface CollectConfigProps<
Config extends ConfigurableBaseConfig = ConfigurableBaseConfig
> {
export interface CollectConfigProps<Config extends object = object> {
/**
* Current (latest) config of the item.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import {
} from '@elastic/eui';
import { txtChangeButton } from './i18n';
import './action_wizard.scss';
import { AnyActionFactory } from '../../services';
import { ActionFactory } from '../../services';

type ActionBaseConfig = object;
type ActionFactoryBaseContext = object;
Expand All @@ -25,19 +25,19 @@ export interface ActionWizardProps {
/**
* List of available action factories
*/
actionFactories: AnyActionFactory[];
actionFactories: ActionFactory[];

/**
* Currently selected action factory
* undefined - is allowed and means that non is selected
*/
currentActionFactory?: AnyActionFactory;
currentActionFactory?: ActionFactory;

/**
* Action factory selected changed
* null - means user click "change" and removed action factory selection
*/
onActionFactoryChange: (actionFactory: AnyActionFactory | null) => void;
onActionFactoryChange: (actionFactory: ActionFactory | null) => void;

/**
* current config for currently selected action factory
Expand Down Expand Up @@ -97,7 +97,7 @@ export const ActionWizard: React.FC<ActionWizardProps> = ({
};

interface SelectedActionFactoryProps {
actionFactory: AnyActionFactory;
actionFactory: ActionFactory;
config: ActionBaseConfig;
context: ActionFactoryBaseContext;
onConfigChange: (config: ActionBaseConfig) => void;
Expand Down Expand Up @@ -153,9 +153,9 @@ const SelectedActionFactory: React.FC<SelectedActionFactoryProps> = ({
};

interface ActionFactorySelectorProps {
actionFactories: AnyActionFactory[];
actionFactories: ActionFactory[];
context: ActionFactoryBaseContext;
onActionFactorySelected: (actionFactory: AnyActionFactory) => void;
onActionFactorySelected: (actionFactory: ActionFactory) => void;
}

export const TEST_SUBJ_ACTION_FACTORY_ITEM = 'action-factory-item';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import React, { useState } from 'react';
import { EuiFieldText, EuiFormRow, EuiSelect, EuiSwitch } from '@elastic/eui';
import { reactToUiComponent } from '../../../../../../src/plugins/kibana_react/public';
import { ActionWizard } from './action_wizard';
import { ActionFactoryDefinition, AnyActionFactory, ActionFactory } from '../../services';
import { ActionFactoryDefinition, ActionFactory } from '../../services';
import { CollectConfigProps } from '../../util';

type ActionBaseConfig = object;
Expand Down Expand Up @@ -88,7 +88,7 @@ export const dashboardDrilldownActionFactory: ActionFactoryDefinition<
useCurrentDashboardFilters: true,
};
},
isConfigValid: config => {
isConfigValid: (config: DashboardDrilldownConfig): config is DashboardDrilldownConfig => {
if (!config.dashboardId) return false;
return true;
},
Expand Down Expand Up @@ -146,7 +146,7 @@ export const urlDrilldownActionFactory: ActionFactoryDefinition<UrlDrilldownConf
openInNewTab: false,
};
},
isConfigValid: config => {
isConfigValid: (config: any): config is UrlDrilldownConfig => {
if (!config.url) return false;
return true;
},
Expand All @@ -161,13 +161,13 @@ export const urlDrilldownActionFactory: ActionFactoryDefinition<UrlDrilldownConf

export const urlFactory = new ActionFactory(urlDrilldownActionFactory);

export function Demo({ actionFactories }: { actionFactories: AnyActionFactory[] }) {
export function Demo({ actionFactories }: { actionFactories: Array<ActionFactory<any>> }) {
const [state, setState] = useState<{
currentActionFactory?: AnyActionFactory;
currentActionFactory?: ActionFactory;
config?: ActionBaseConfig;
}>({});

function changeActionFactory(newActionFactory: AnyActionFactory | null) {
function changeActionFactory(newActionFactory: ActionFactory | null) {
if (!newActionFactory) {
// removing action factory
return setState({});
Expand Down
2 changes: 0 additions & 2 deletions x-pack/plugins/advanced_ui_actions/public/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,7 @@ export {
export { ActionWizard } from './components';
export {
ActionFactoryDefinition as AdvancedUiActionsActionFactoryDefinition,
AnyActionFactoryDefinition as AdvancedUiActionsAnyActionFactoryDefinition,
ActionFactory as AdvancedUiActionsActionFactory,
AnyActionFactory as AdvancedUiActionsAnyActionFactory,
} from './services/action_factory_service';
export {
Configurable as AdvancedUiActionsConfigurable,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,5 @@
/* eslint-disable */

export {
ActionFactory, AnyActionFactory
ActionFactory
} from '../../../../../../src/plugins/ui_actions/public/actions/action_factory';
Loading