Examples/expressions2 (#90140)

This commit is contained in:
Peter Pisljar 2021-02-03 16:06:26 +01:00 committed by GitHub
parent c6be748a97
commit 2145768c0d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 146 additions and 8 deletions

View file

@ -63,7 +63,7 @@ export function ActionsExpressionsExample({ expressions, actions }: Props) {
</EuiTitle> </EuiTitle>
</EuiPageHeaderSection> </EuiPageHeaderSection>
</EuiPageHeader> </EuiPageHeader>
<EuiPageContent> <EuiPageContent data-test-subj="expressionsActionsTest">
<EuiPageContentBody> <EuiPageContentBody>
<EuiFlexGroup> <EuiFlexGroup>
<EuiFlexItem> <EuiFlexItem>

View file

@ -0,0 +1,102 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* and the Server Side Public License, v 1; you may not use this file except in
* compliance with, at your election, the Elastic License or the Server Side
* Public License, v 1.
*/
import React, { useState } from 'react';
import {
EuiFlexItem,
EuiFlexGroup,
EuiPageBody,
EuiPageContent,
EuiPageContentBody,
EuiPageHeader,
EuiPageHeaderSection,
EuiPanel,
EuiText,
EuiTitle,
} from '@elastic/eui';
import {
ExpressionsStart,
ReactExpressionRenderer,
ExpressionsInspectorAdapter,
} from '../../../src/plugins/expressions/public';
import { ExpressionEditor } from './editor/expression_editor';
import { UiActionsStart } from '../../../src/plugins/ui_actions/public';
interface Props {
expressions: ExpressionsStart;
actions: UiActionsStart;
}
export function ActionsExpressionsExample2({ expressions, actions }: Props) {
const [expression, updateExpression] = useState(
'button name="click me" href="http://www.google.com" color={var color}'
);
const [variables, updateVariables] = useState({
color: 'blue',
});
const expressionChanged = (value: string) => {
updateExpression(value);
};
const inspectorAdapters = {
expression: new ExpressionsInspectorAdapter(),
};
const handleEvents = (event: any) => {
updateVariables({ color: event.value.href === 'http://www.google.com' ? 'red' : 'blue' });
};
return (
<EuiPageBody>
<EuiPageHeader>
<EuiPageHeaderSection>
<EuiTitle size="l">
<h1>Actions from expression renderers</h1>
</EuiTitle>
</EuiPageHeaderSection>
</EuiPageHeader>
<EuiPageContent>
<EuiPageContentBody data-test-subj="expressionsVariablesTest">
<EuiFlexGroup>
<EuiFlexItem>
<EuiText>
This example is similar to previous one, but clicking the button will rerender the
expression with new set of variables.
</EuiText>
</EuiFlexItem>
</EuiFlexGroup>
<EuiFlexGroup gutterSize="l">
<EuiFlexItem>
<EuiPanel data-test-subj="expressionEditor" paddingSize="none" role="figure">
<ExpressionEditor value={expression} onChange={expressionChanged} />
</EuiPanel>
</EuiFlexItem>
<EuiFlexItem>
<EuiPanel paddingSize="none" role="figure">
<ReactExpressionRenderer
data-test-subj="expressionsVariablesTestRenderer"
expression={expression}
debug={true}
inspectorAdapters={inspectorAdapters}
variables={variables}
onEvent={handleEvents}
renderError={(message: any) => {
return <div>{message}</div>;
}}
/>
</EuiPanel>
</EuiFlexItem>
</EuiFlexGroup>
</EuiPageContentBody>
</EuiPageContent>
</EuiPageBody>
);
}

View file

@ -25,6 +25,7 @@ import { RunExpressionsExample } from './run_expressions';
import { RenderExpressionsExample } from './render_expressions'; import { RenderExpressionsExample } from './render_expressions';
import { ActionsExpressionsExample } from './actions_and_expressions'; import { ActionsExpressionsExample } from './actions_and_expressions';
import { UiActionsStart } from '../../../src/plugins/ui_actions/public'; import { UiActionsStart } from '../../../src/plugins/ui_actions/public';
import { ActionsExpressionsExample2 } from './actions_and_expressions2';
interface Props { interface Props {
expressions: ExpressionsStart; expressions: ExpressionsStart;
@ -64,6 +65,10 @@ const ExpressionsExplorer = ({ expressions, inspector, actions }: Props) => {
<EuiSpacer /> <EuiSpacer />
<ActionsExpressionsExample expressions={expressions} actions={actions} /> <ActionsExpressionsExample expressions={expressions} actions={actions} />
<EuiSpacer />
<ActionsExpressionsExample2 expressions={expressions} actions={actions} />
</EuiPageContentBody> </EuiPageContentBody>
</EuiPageContent> </EuiPageContent>
</EuiPageBody> </EuiPageBody>

View file

@ -10,6 +10,7 @@ import { i18n } from '@kbn/i18n';
import { ExpressionFunctionDefinition } from '../../../../src/plugins/expressions/common'; import { ExpressionFunctionDefinition } from '../../../../src/plugins/expressions/common';
interface Arguments { interface Arguments {
color: string;
href: string; href: string;
name: string; name: string;
} }
@ -24,15 +25,20 @@ export type ExpressionFunctionButton = ExpressionFunctionDefinition<
export const buttonFn: ExpressionFunctionButton = { export const buttonFn: ExpressionFunctionButton = {
name: 'button', name: 'button',
args: { args: {
color: {
help: i18n.translate('expressions.functions.button.args.color', {
defaultMessage: 'Color of the button',
}),
},
href: { href: {
help: i18n.translate('expressions.functions.font.args.href', { help: i18n.translate('expressions.functions.button.args.href', {
defaultMessage: 'Link to which to navigate', defaultMessage: 'Link to which to navigate',
}), }),
types: ['string'], types: ['string'],
required: true, required: true,
}, },
name: { name: {
help: i18n.translate('expressions.functions.font.args.name', { help: i18n.translate('expressions.functions.button.args.name', {
defaultMessage: 'Name of the button', defaultMessage: 'Name of the button',
}), }),
types: ['string'], types: ['string'],

View file

@ -26,8 +26,17 @@ export const buttonRenderer: ExpressionRenderDefinition<any> = {
}; };
const renderDebug = () => ( const renderDebug = () => (
<div style={{ width: domNode.offsetWidth, height: domNode.offsetHeight }}> <div
<EuiButton data-test-subj="testExpressionButton" onClick={buttonClick}> style={{
width: domNode.offsetWidth,
height: domNode.offsetHeight,
}}
>
<EuiButton
data-test-subj="testExpressionButton"
onClick={buttonClick}
style={{ backgroundColor: config.color || 'white' }}
>
{config.name} {config.name}
</EuiButton> </EuiButton>
</div> </div>

View file

@ -83,7 +83,7 @@ export class ExpressionRenderHandler {
reload: () => { reload: () => {
this.updateSubject.next(null); this.updateSubject.next(null);
}, },
update: (params) => { update: (params: UpdateValue) => {
this.updateSubject.next(params); this.updateSubject.next(params);
}, },
event: (data) => { event: (data) => {

View file

@ -7,13 +7,14 @@
*/ */
import expect from '@kbn/expect'; import expect from '@kbn/expect';
import testSubjSelector from '@kbn/test-subj-selector';
import { PluginFunctionalProviderContext } from 'test/plugin_functional/services'; import { PluginFunctionalProviderContext } from 'test/plugin_functional/services';
// eslint-disable-next-line import/no-default-export // eslint-disable-next-line import/no-default-export
export default function ({ getService }: PluginFunctionalProviderContext) { export default function ({ getService }: PluginFunctionalProviderContext) {
const testSubjects = getService('testSubjects'); const testSubjects = getService('testSubjects');
const retry = getService('retry'); const retry = getService('retry');
const find = getService('find');
const browser = getService('browser'); const browser = getService('browser');
describe('', () => { describe('', () => {
@ -33,8 +34,23 @@ export default function ({ getService }: PluginFunctionalProviderContext) {
}); });
}); });
it('updates the variable', async () => {
const selector = `${testSubjSelector('expressionsVariablesTest')} ${testSubjSelector(
'testExpressionButton'
)}`;
await find.clickByCssSelector(selector);
await retry.try(async () => {
const el = await find.byCssSelector(selector);
const style = await el.getAttribute('style');
expect(style).to.contain('red');
});
});
it('emits an action and navigates', async () => { it('emits an action and navigates', async () => {
await testSubjects.click('testExpressionButton'); const selector = `${testSubjSelector('expressionsActionsTest')} ${testSubjSelector(
'testExpressionButton'
)}`;
await find.clickByCssSelector(selector);
await retry.try(async () => { await retry.try(async () => {
const text = await browser.getCurrentUrl(); const text = await browser.getCurrentUrl();
expect(text).to.be('https://www.google.com/?gws_rd=ssl'); expect(text).to.be('https://www.google.com/?gws_rd=ssl');