Skip to content

Commit 50f9a97

Browse files
authored
[Drilldowns] misc improvements & fixes (#75276)
Added support for isCompatible. It is checked during execution. Pass actionFactory context into createConfig, IsConfigValid Fix bug that selectedTriggers wasn't reset when switching action factories Check if license is active in action factories
1 parent e30220f commit 50f9a97

File tree

9 files changed

+83
-17
lines changed

9 files changed

+83
-17
lines changed

src/plugins/kibana_utils/public/ui/configurable.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,12 @@ export interface Configurable<Config extends object = object, Context = object>
2626
/**
2727
* Create default config for this item, used when item is created for the first time.
2828
*/
29-
readonly createConfig: () => Config;
29+
readonly createConfig: (context: Context) => Config;
3030

3131
/**
3232
* Is this config valid. Used to validate user's input before saving.
3333
*/
34-
readonly isConfigValid: (config: Config) => boolean;
34+
readonly isConfigValid: (config: Config, context: Context) => boolean;
3535

3636
/**
3737
* `UiComponent` to be rendered when collecting configuration for this item.

x-pack/examples/ui_actions_enhanced_examples/public/dashboard_hello_world_only_range_select_drilldown/index.tsx

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import { UiActionsEnhancedDrilldownDefinition as Drilldown } from '../../../../p
1111
import { RangeSelectContext } from '../../../../../src/plugins/embeddable/public';
1212
import { CollectConfigProps } from '../../../../../src/plugins/kibana_utils/public';
1313
import { SELECT_RANGE_TRIGGER } from '../../../../../src/plugins/ui_actions/public';
14+
import { BaseActionFactoryContext } from '../../../../plugins/ui_actions_enhanced/public/dynamic_actions';
1415

1516
export interface Config {
1617
name: string;
@@ -52,10 +53,24 @@ export class DashboardHelloWorldOnlyRangeSelectDrilldown
5253
name: '',
5354
});
5455

55-
public readonly isConfigValid = (config: Config): config is Config => {
56+
public readonly isConfigValid = (
57+
config: Config,
58+
context: BaseActionFactoryContext<typeof SELECT_RANGE_TRIGGER>
59+
): config is Config => {
60+
// eslint-disable-next-line no-console
61+
console.log('Showcasing, that can access action factory context:', context);
62+
5663
return !!config.name;
5764
};
5865

66+
/**
67+
* Showcase isCompatible. Disabled drilldown action in case if range.length === 0
68+
*/
69+
isCompatible(config: Config, context: RangeSelectContext): Promise<boolean> {
70+
if (context.data.range.length === 0) return Promise.resolve(false);
71+
return Promise.resolve(true);
72+
}
73+
5974
public readonly execute = async (config: Config, context: RangeSelectContext) => {
6075
alert(`Hello, ${config.name}, your selected range: ${JSON.stringify(context.data.range)}`);
6176
};

x-pack/plugins/ui_actions_enhanced/public/components/action_wizard/test_data.tsx

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -220,7 +220,9 @@ export function Demo({ actionFactories }: { actionFactories: Array<ActionFactory
220220

221221
setState({
222222
currentActionFactory: newActionFactory,
223-
config: newActionFactory.createConfig(),
223+
config: newActionFactory.createConfig({
224+
triggers: state.selectedTriggers ?? [],
225+
}),
224226
});
225227
}
226228

@@ -255,7 +257,11 @@ export function Demo({ actionFactories }: { actionFactories: Array<ActionFactory
255257
<div>Action Factory Config: {JSON.stringify(state.config)}</div>
256258
<div>
257259
Is config valid:{' '}
258-
{JSON.stringify(state.currentActionFactory?.isConfigValid(state.config!) ?? false)}
260+
{JSON.stringify(
261+
state.currentActionFactory?.isConfigValid(state.config!, {
262+
triggers: state.selectedTriggers ?? [],
263+
}) ?? false
264+
)}
259265
</div>
260266
<div>Picked trigger: {state.selectedTriggers?.[0]}</div>
261267
</>

x-pack/plugins/ui_actions_enhanced/public/drilldowns/components/flyout_drilldown_wizard/flyout_drilldown_wizard.tsx

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ export interface FlyoutDrilldownWizardProps<
5757
}
5858

5959
function useWizardConfigState(
60+
actionFactoryContext: BaseActionFactoryContext,
6061
initialDrilldownWizardConfig?: DrilldownWizardConfig
6162
): [
6263
DrilldownWizardConfig,
@@ -102,7 +103,10 @@ function useWizardConfigState(
102103
setWizardConfig({
103104
...wizardConfig,
104105
actionFactory,
105-
actionConfig: actionConfigCache[actionFactory.id] ?? actionFactory.createConfig(),
106+
actionConfig:
107+
actionConfigCache[actionFactory.id] ??
108+
actionFactory.createConfig(actionFactoryContext),
109+
selectedTriggers: [],
106110
});
107111
} else {
108112
if (wizardConfig.actionFactory?.id) {
@@ -147,7 +151,18 @@ export function FlyoutDrilldownWizard<CurrentActionConfig extends object = objec
147151
const [
148152
wizardConfig,
149153
{ setActionFactory, setActionConfig, setName, setSelectedTriggers },
150-
] = useWizardConfigState(initialDrilldownWizardConfig);
154+
] = useWizardConfigState(
155+
{ ...extraActionFactoryContext, triggers: supportedTriggers },
156+
initialDrilldownWizardConfig
157+
);
158+
159+
const actionFactoryContext: BaseActionFactoryContext = useMemo(
160+
() => ({
161+
...extraActionFactoryContext,
162+
triggers: wizardConfig.selectedTriggers ?? [],
163+
}),
164+
[extraActionFactoryContext, wizardConfig.selectedTriggers]
165+
);
151166

152167
const isActionValid = (
153168
config: DrilldownWizardConfig
@@ -157,17 +172,12 @@ export function FlyoutDrilldownWizard<CurrentActionConfig extends object = objec
157172
if (!wizardConfig.actionConfig) return false;
158173
if (!wizardConfig.selectedTriggers || wizardConfig.selectedTriggers.length === 0) return false;
159174

160-
return wizardConfig.actionFactory.isConfigValid(wizardConfig.actionConfig);
175+
return wizardConfig.actionFactory.isConfigValid(
176+
wizardConfig.actionConfig,
177+
actionFactoryContext
178+
);
161179
};
162180

163-
const actionFactoryContext: BaseActionFactoryContext = useMemo(
164-
() => ({
165-
...extraActionFactoryContext,
166-
triggers: wizardConfig.selectedTriggers ?? [],
167-
}),
168-
[extraActionFactoryContext, wizardConfig.selectedTriggers]
169-
);
170-
171181
const footer = (
172182
<EuiButton
173183
onClick={() => {

x-pack/plugins/ui_actions_enhanced/public/drilldowns/drilldown_definition.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,15 @@ export interface DrilldownDefinition<
106106
*/
107107
getDisplayName: () => string;
108108

109+
/**
110+
* isCompatible during execution
111+
* Could be used to prevent drilldown from execution
112+
*/
113+
isCompatible?(
114+
config: Config,
115+
context: ExecutionContext | ActionExecutionContext<ExecutionContext>
116+
): Promise<boolean>;
117+
109118
/**
110119
* Implements the "navigation" action of the drilldown. This happens when
111120
* user clicks something in the UI that executes a trigger to which this

x-pack/plugins/ui_actions_enhanced/public/dynamic_actions/action_factory.test.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,14 @@ describe('License & ActionFactory', () => {
3737
expect(factory.isCompatibleLicence()).toBe(false);
3838
});
3939

40+
test('licence has expired', async () => {
41+
const factory = new ActionFactory({ ...def, minimalLicense: 'gold' }, () =>
42+
licensingMock.createLicense({ license: { type: 'gold', status: 'expired' } })
43+
);
44+
expect(await factory.isCompatible({ triggers: [] })).toBe(true);
45+
expect(factory.isCompatibleLicence()).toBe(false);
46+
});
47+
4048
test('enough license level', async () => {
4149
const factory = new ActionFactory({ ...def, minimalLicense: 'gold' }, () =>
4250
licensingMock.createLicense({ license: { type: 'gold' } })

x-pack/plugins/ui_actions_enhanced/public/dynamic_actions/action_factory.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,8 @@ export class ActionFactory<
7070
*/
7171
public isCompatibleLicence() {
7272
if (!this.minimalLicense) return true;
73-
return this.getLicence().hasAtLeast(this.minimalLicense);
73+
const licence = this.getLicence();
74+
return licence.isAvailable && licence.isActive && licence.hasAtLeast(this.minimalLicense);
7475
}
7576

7677
public create(

x-pack/plugins/ui_actions_enhanced/public/services/ui_actions_service_enhancements.test.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,5 +75,18 @@ describe('UiActionsService', () => {
7575
'Action factory [actionFactoryId = UNKNOWN_ID] does not exist.'
7676
);
7777
});
78+
79+
test('isCompatible from definition is used on registered factory', async () => {
80+
const service = new UiActionsServiceEnhancements({ getLicenseInfo });
81+
82+
service.registerActionFactory({
83+
...factoryDefinition1,
84+
isCompatible: () => Promise.resolve(false),
85+
});
86+
87+
await expect(
88+
service.getActionFactory(factoryDefinition1.id).isCompatible({ triggers: [] })
89+
).resolves.toBe(false);
90+
});
7891
});
7992
});

x-pack/plugins/ui_actions_enhanced/public/services/ui_actions_service_enhancements.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ export class UiActionsServiceEnhancements {
9595
getHref,
9696
minimalLicense,
9797
supportedTriggers,
98+
isCompatible,
9899
}: DrilldownDefinition<Config, SupportedTriggers, FactoryContext, ExecutionContext>): void => {
99100
const actionFactory: ActionFactoryDefinition<
100101
Config,
@@ -119,6 +120,9 @@ export class UiActionsServiceEnhancements {
119120
getDisplayName: () => serializedAction.name,
120121
execute: async (context) => await execute(serializedAction.config, context),
121122
getHref: getHref ? async (context) => getHref(serializedAction.config, context) : undefined,
123+
isCompatible: isCompatible
124+
? async (context) => isCompatible(serializedAction.config, context)
125+
: undefined,
122126
}),
123127
} as ActionFactoryDefinition<Config, SupportedTriggers, FactoryContext, ExecutionContext>;
124128

0 commit comments

Comments
 (0)