mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 09:19:04 -04:00
Add overview section to actions and triggers example (#175152)
PR updates actions and triggers example with an "Overview" section better explaining the top level concepts. PR also re-works the hello world example to have a better explaination of what it does and simplify the example ### before <img width="800" alt="Screenshot 2024-01-18 at 12 08 44 PM" src="5969b35e
-a307-402a-aba4-a5b4ffa9920b"> ### after <img width="800" alt="Screenshot 2024-01-18 at 12 06 46 PM" src="e2eb416e
-c7a0-4a04-83e8-2383fbe12dae"> --------- Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
parent
e404798a15
commit
33077eaa99
5 changed files with 168 additions and 76 deletions
|
@ -33,7 +33,6 @@ export class UiActionExamplesPlugin
|
|||
openModal: (await core.getStartServices())[0].overlays.openModal,
|
||||
}));
|
||||
|
||||
uiActions.registerAction(helloWorldAction);
|
||||
uiActions.addTriggerAction(helloWorldTrigger.id, helloWorldAction);
|
||||
}
|
||||
|
||||
|
|
|
@ -6,104 +6,50 @@
|
|||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import React, { useState } from 'react';
|
||||
import React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
|
||||
import {
|
||||
EuiPage,
|
||||
EuiButton,
|
||||
EuiPageBody,
|
||||
EuiPageTemplate,
|
||||
EuiPageSection,
|
||||
EuiSpacer,
|
||||
EuiText,
|
||||
EuiFieldText,
|
||||
EuiCallOut,
|
||||
EuiPageHeader,
|
||||
EuiModalBody,
|
||||
} from '@elastic/eui';
|
||||
import { toMountPoint } from '@kbn/kibana-react-plugin/public';
|
||||
import { UiActionsStart, createAction } from '@kbn/ui-actions-plugin/public';
|
||||
import { UiActionsStart } from '@kbn/ui-actions-plugin/public';
|
||||
import { AppMountParameters, OverlayStart } from '@kbn/core/public';
|
||||
import { HELLO_WORLD_TRIGGER_ID, ACTION_HELLO_WORLD } from '@kbn/ui-actions-examples-plugin/public';
|
||||
import { TriggerContextExample } from './trigger_context_example';
|
||||
import { ContextMenuExamples } from './context_menu_examples';
|
||||
import { Overview } from './overview';
|
||||
import { HelloWorldExample } from './hello_world_example';
|
||||
|
||||
interface Props {
|
||||
uiActionsApi: UiActionsStart;
|
||||
uiActionsStartService: UiActionsStart;
|
||||
openModal: OverlayStart['openModal'];
|
||||
}
|
||||
|
||||
const ActionsExplorer = ({ uiActionsApi, openModal }: Props) => {
|
||||
const [name, setName] = useState('Waldo');
|
||||
const [confirmationText, setConfirmationText] = useState('');
|
||||
const ActionsExplorer = ({ uiActionsStartService, openModal }: Props) => {
|
||||
return (
|
||||
<EuiPage>
|
||||
<EuiPageBody>
|
||||
<EuiPageSection>
|
||||
<EuiPageHeader pageTitle={'Ui Actions Explorer'} />
|
||||
<EuiPageHeader pageTitle="Actions and Triggers" />
|
||||
</EuiPageSection>
|
||||
<EuiPageTemplate.Section>
|
||||
<EuiPageSection>
|
||||
<EuiText>
|
||||
<p>
|
||||
By default there is a single action attached to the `HELLO_WORLD_TRIGGER`. Clicking
|
||||
this button will cause it to be executed immediately.
|
||||
</p>
|
||||
</EuiText>
|
||||
<EuiButton
|
||||
data-test-subj="emitHelloWorldTrigger"
|
||||
onClick={() => uiActionsApi.executeTriggerActions(HELLO_WORLD_TRIGGER_ID, {})}
|
||||
>
|
||||
Say hello world!
|
||||
</EuiButton>
|
||||
|
||||
<EuiText>
|
||||
<p>
|
||||
Lets dynamically add new actions to this trigger. After you click this button, click
|
||||
the above button again. This time it should offer you multiple options to choose
|
||||
from. Using the UI Action and Trigger API makes your plugin extensible by other
|
||||
plugins. Any actions attached to the `HELLO_WORLD_TRIGGER_ID` will show up here!
|
||||
</p>
|
||||
<EuiFieldText prepend="Name" value={name} onChange={(e) => setName(e.target.value)} />
|
||||
<EuiButton
|
||||
data-test-subj="addDynamicAction"
|
||||
onClick={() => {
|
||||
const dynamicAction = createAction({
|
||||
id: `${ACTION_HELLO_WORLD}-${name}`,
|
||||
type: ACTION_HELLO_WORLD,
|
||||
getDisplayName: () => `Say hello to ${name}`,
|
||||
execute: async () => {
|
||||
const overlay = openModal(
|
||||
toMountPoint(
|
||||
<EuiModalBody>
|
||||
<EuiText data-test-subj="dynamicHelloWorldActionText">
|
||||
{`Hello ${name}`}
|
||||
</EuiText>{' '}
|
||||
<EuiButton data-test-subj="closeModal" onClick={() => overlay.close()}>
|
||||
Close
|
||||
</EuiButton>
|
||||
</EuiModalBody>
|
||||
)
|
||||
);
|
||||
},
|
||||
});
|
||||
uiActionsApi.addTriggerAction(HELLO_WORLD_TRIGGER_ID, dynamicAction);
|
||||
setConfirmationText(
|
||||
`You've successfully added a new action: ${dynamicAction.getDisplayName({
|
||||
trigger: uiActionsApi.getTrigger(HELLO_WORLD_TRIGGER_ID),
|
||||
})}. Refresh the page to reset state. It's up to the user of the system to persist state like this.`
|
||||
);
|
||||
}}
|
||||
>
|
||||
Say hello to me!
|
||||
</EuiButton>
|
||||
{confirmationText !== '' ? <EuiCallOut>{confirmationText}</EuiCallOut> : undefined}
|
||||
</EuiText>
|
||||
<Overview />
|
||||
|
||||
<EuiSpacer />
|
||||
|
||||
<TriggerContextExample uiActionsApi={uiActionsApi} />
|
||||
<HelloWorldExample
|
||||
uiActionsStartService={uiActionsStartService}
|
||||
openModal={openModal}
|
||||
/>
|
||||
|
||||
<EuiSpacer />
|
||||
|
||||
<TriggerContextExample uiActionsApi={uiActionsStartService} />
|
||||
|
||||
<EuiSpacer />
|
||||
|
||||
|
|
94
examples/ui_actions_explorer/public/hello_world_example.tsx
Normal file
94
examples/ui_actions_explorer/public/hello_world_example.tsx
Normal file
|
@ -0,0 +1,94 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0 and the Server Side Public License, v 1; you may not use this file except
|
||||
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import React, { useState } from 'react';
|
||||
|
||||
import { EuiButton, EuiSpacer, EuiText, EuiModalBody, EuiLink, EuiSwitch } from '@elastic/eui';
|
||||
import { toMountPoint } from '@kbn/kibana-react-plugin/public';
|
||||
import { UiActionsStart, createAction } from '@kbn/ui-actions-plugin/public';
|
||||
import { OverlayStart } from '@kbn/core/public';
|
||||
import { HELLO_WORLD_TRIGGER_ID, ACTION_HELLO_WORLD } from '@kbn/ui-actions-examples-plugin/public';
|
||||
|
||||
const DYNAMIC_ACTION_ID = `${ACTION_HELLO_WORLD}-Waldo`;
|
||||
|
||||
interface Props {
|
||||
uiActionsStartService: UiActionsStart;
|
||||
openModal: OverlayStart['openModal'];
|
||||
}
|
||||
|
||||
export const HelloWorldExample = ({ uiActionsStartService, openModal }: Props) => {
|
||||
const [isChecked, setIsChecked] = useState(false);
|
||||
|
||||
const actionsMessage = isChecked ? '2 actions attached' : '1 action attached';
|
||||
|
||||
return (
|
||||
<>
|
||||
<EuiText>
|
||||
<h1>Hello world example</h1>
|
||||
<p>
|
||||
The{' '}
|
||||
<EuiLink
|
||||
href="https://github.com/elastic/kibana/tree/main/examples/ui_action_examples"
|
||||
target="_blank"
|
||||
>
|
||||
ui_action_example plugin
|
||||
</EuiLink>{' '}
|
||||
registers the <em>HELLO_WORLD_TRIGGER_ID</em> trigger and attaches the{' '}
|
||||
<em>ACTION_HELLO_WORLD</em> action to the trigger. The <em>ACTION_HELLO_WORLD</em> opens a
|
||||
modal when executed. Fire the "Hello world" event by clicking the button below.
|
||||
</p>
|
||||
</EuiText>
|
||||
<EuiButton
|
||||
data-test-subj="emitHelloWorldTrigger"
|
||||
onClick={() => uiActionsStartService.getTrigger(HELLO_WORLD_TRIGGER_ID).exec({})}
|
||||
>
|
||||
Click me to fire "Hello world" event ({actionsMessage})
|
||||
</EuiButton>
|
||||
|
||||
<EuiSpacer />
|
||||
|
||||
<EuiText>
|
||||
<p>
|
||||
You can dynamically add a new action to a trigger. Click the switch below to attach a
|
||||
second action to <em>HELLO_WORLD_TRIGGER_ID</em> trigger. What do you think will happen
|
||||
when you click the button and the trigger has multiple actions?
|
||||
</p>
|
||||
<EuiSwitch
|
||||
data-test-subj="addDynamicAction"
|
||||
label={'Attach second action to "Hello world" event'}
|
||||
checked={isChecked}
|
||||
onChange={(e) => {
|
||||
setIsChecked(e.target.checked);
|
||||
if (e.target.checked) {
|
||||
const dynamicAction = createAction({
|
||||
id: DYNAMIC_ACTION_ID,
|
||||
type: ACTION_HELLO_WORLD,
|
||||
getDisplayName: () => 'Say hello to Waldo',
|
||||
execute: async () => {
|
||||
const overlay = openModal(
|
||||
toMountPoint(
|
||||
<EuiModalBody>
|
||||
<EuiText data-test-subj="dynamicHelloWorldActionText">Hello Waldo</EuiText>{' '}
|
||||
<EuiButton data-test-subj="closeModal" onClick={() => overlay.close()}>
|
||||
Close
|
||||
</EuiButton>
|
||||
</EuiModalBody>
|
||||
)
|
||||
);
|
||||
},
|
||||
});
|
||||
uiActionsStartService.addTriggerAction(HELLO_WORLD_TRIGGER_ID, dynamicAction);
|
||||
} else {
|
||||
uiActionsStartService.detachAction(HELLO_WORLD_TRIGGER_ID, DYNAMIC_ACTION_ID);
|
||||
}
|
||||
}}
|
||||
/>
|
||||
</EuiText>
|
||||
</>
|
||||
);
|
||||
};
|
55
examples/ui_actions_explorer/public/overview.tsx
Normal file
55
examples/ui_actions_explorer/public/overview.tsx
Normal file
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0 and the Server Side Public License, v 1; you may not use this file except
|
||||
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
|
||||
import { EuiText, EuiLink } from '@elastic/eui';
|
||||
|
||||
export const Overview = () => {
|
||||
return (
|
||||
<EuiText>
|
||||
<h1>Overview</h1>
|
||||
<p>
|
||||
Actions and triggers are an event system abstraction that decouples firing an event and
|
||||
responding to an event.
|
||||
</p>
|
||||
Key concepts:
|
||||
<ul>
|
||||
<li>
|
||||
<strong>Trigger</strong> is an id that represents an event type, for example
|
||||
<em>PANEL_CLICK</em>.
|
||||
</li>
|
||||
<li>
|
||||
<strong>Action</strong> is a{' '}
|
||||
<EuiLink
|
||||
href="https://github.com/elastic/kibana/blob/main/src/plugins/ui_actions/public/actions/action.ts"
|
||||
target="_blank"
|
||||
>
|
||||
class
|
||||
</EuiLink>{' '}
|
||||
that responds to an event. Multiple actions can be registered to an event type. Actions
|
||||
can respond to multiple event types.
|
||||
</li>
|
||||
<li>
|
||||
<strong>Context</strong> is runtime state passed between an event and the responder of an
|
||||
event.
|
||||
</li>
|
||||
</ul>
|
||||
<p>
|
||||
The purpose for the event system abstraction is to make event handling extensible, allowing
|
||||
plugins to register their own event types and responses and register responses to existing
|
||||
event types.
|
||||
</p>
|
||||
<p>
|
||||
Use triggers to make your plugin extensible. For example, your plugin could register a
|
||||
trigger. Then, other plugins can extend your plugin by registering new actions for the
|
||||
trigger. Finally, when the trigger is fired, all attached actions are available.
|
||||
</p>
|
||||
</EuiText>
|
||||
);
|
||||
};
|
|
@ -69,7 +69,7 @@ export class UiActionsExplorerPlugin implements Plugin<void, void, {}, StartDeps
|
|||
const [coreStart, depsStart] = await core.getStartServices();
|
||||
const { renderApp } = await import('./app');
|
||||
return renderApp(
|
||||
{ uiActionsApi: depsStart.uiActions, openModal: coreStart.overlays.openModal },
|
||||
{ uiActionsStartService: depsStart.uiActions, openModal: coreStart.overlays.openModal },
|
||||
params
|
||||
);
|
||||
},
|
||||
|
@ -77,10 +77,8 @@ export class UiActionsExplorerPlugin implements Plugin<void, void, {}, StartDeps
|
|||
|
||||
deps.developerExamples.register({
|
||||
appId: 'uiActionsExplorer',
|
||||
title: 'Ui Actions & Triggers',
|
||||
description: `Ui Actions can be used to make any part of your UI extensible. It has built in support for
|
||||
context menus, but you can also render all actions attached to a given trigger however you like, just how
|
||||
panel badges and panel notifications does.`,
|
||||
title: 'Actions & Triggers',
|
||||
description: `Learn how to extent Kibana's UI event system with actions and triggers. In the screen shot, plugins extend dashboard panels by attaching new actions to PANEL_BADGE_TRIGGER and CONTEXT_MENU_TRIGGER triggers.`,
|
||||
image,
|
||||
links: [
|
||||
{
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue