mirror of
https://github.com/elastic/kibana.git
synced 2025-06-28 03:01:21 -04:00
[Presentation] Migrate all usages of EuiPage*_Deprecated (#161496)
closes https://github.com/elastic/kibana/issues/161428 PR also updates examples title. Instead of naming the embeddable used, the title now reflects what the example demonstrates. * "Hello world embeddable" -> "Render embeddable" * "Todo embeddable" -> "Update embeddable state" * "List container embeddable" -> "Groups of embeddables" * "Dynamically adding children to a container" -> "Context menu" There is a lot more that could be done to enhance these examples, but I did not want to get more side tracked then I already did. --------- Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
parent
9e5844f715
commit
d3d0cdba73
7 changed files with 187 additions and 300 deletions
|
@ -10,7 +10,7 @@ import React from 'react';
|
||||||
import ReactDOM from 'react-dom';
|
import ReactDOM from 'react-dom';
|
||||||
import { BrowserRouter as Router, withRouter, RouteComponentProps } from 'react-router-dom';
|
import { BrowserRouter as Router, withRouter, RouteComponentProps } from 'react-router-dom';
|
||||||
import { Route } from '@kbn/shared-ux-router';
|
import { Route } from '@kbn/shared-ux-router';
|
||||||
import { EuiPage, EuiPageSideBar_Deprecated as EuiPageSideBar, EuiSideNav } from '@elastic/eui';
|
import { EuiPageTemplate, EuiSideNav } from '@elastic/eui';
|
||||||
|
|
||||||
import { EmbeddableStart } from '@kbn/embeddable-plugin/public';
|
import { EmbeddableStart } from '@kbn/embeddable-plugin/public';
|
||||||
import { UiActionsStart } from '@kbn/ui-actions-plugin/public';
|
import { UiActionsStart } from '@kbn/ui-actions-plugin/public';
|
||||||
|
@ -51,7 +51,7 @@ const Nav = withRouter(({ history, navigateToApp, pages }: NavProps) => {
|
||||||
<EuiSideNav
|
<EuiSideNav
|
||||||
items={[
|
items={[
|
||||||
{
|
{
|
||||||
name: 'Embeddable explorer',
|
name: 'Embeddable examples',
|
||||||
id: 'home',
|
id: 'home',
|
||||||
items: [...navItems],
|
items: [...navItems],
|
||||||
},
|
},
|
||||||
|
@ -81,7 +81,7 @@ const EmbeddableExplorerApp = ({
|
||||||
}: Props) => {
|
}: Props) => {
|
||||||
const pages: PageDef[] = [
|
const pages: PageDef[] = [
|
||||||
{
|
{
|
||||||
title: 'Hello world embeddable',
|
title: 'Render embeddable',
|
||||||
id: 'helloWorldEmbeddableSection',
|
id: 'helloWorldEmbeddableSection',
|
||||||
component: (
|
component: (
|
||||||
<HelloWorldEmbeddableExample
|
<HelloWorldEmbeddableExample
|
||||||
|
@ -90,7 +90,7 @@ const EmbeddableExplorerApp = ({
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'Todo embeddable',
|
title: 'Update embeddable state',
|
||||||
id: 'todoEmbeddableSection',
|
id: 'todoEmbeddableSection',
|
||||||
component: (
|
component: (
|
||||||
<TodoEmbeddableExample
|
<TodoEmbeddableExample
|
||||||
|
@ -99,17 +99,16 @@ const EmbeddableExplorerApp = ({
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'List container embeddable',
|
title: 'Groups of embeddables',
|
||||||
id: 'listContainerSection',
|
id: 'listContainerSection',
|
||||||
component: (
|
component: (
|
||||||
<ListContainerExample
|
<ListContainerExample
|
||||||
listContainerEmbeddableFactory={embeddableExamples.factories.getListContainerEmbeddableFactory()}
|
listContainerEmbeddableFactory={embeddableExamples.factories.getListContainerEmbeddableFactory()}
|
||||||
searchableListContainerEmbeddableFactory={embeddableExamples.factories.getSearchableListContainerEmbeddableFactory()}
|
|
||||||
/>
|
/>
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'Dynamically adding children to a container',
|
title: 'Context menu',
|
||||||
id: 'embeddablePanelExample',
|
id: 'embeddablePanelExample',
|
||||||
component: (
|
component: (
|
||||||
<EmbeddablePanelExample
|
<EmbeddablePanelExample
|
||||||
|
@ -126,12 +125,12 @@ const EmbeddableExplorerApp = ({
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Router basename={basename}>
|
<Router basename={basename}>
|
||||||
<EuiPage>
|
<EuiPageTemplate offset={0}>
|
||||||
<EuiPageSideBar>
|
<EuiPageTemplate.Sidebar>
|
||||||
<Nav navigateToApp={navigateToApp} pages={pages} />
|
<Nav navigateToApp={navigateToApp} pages={pages} />
|
||||||
</EuiPageSideBar>
|
</EuiPageTemplate.Sidebar>
|
||||||
{routes}
|
{routes}
|
||||||
</EuiPage>
|
</EuiPageTemplate>
|
||||||
</Router>
|
</Router>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
@ -7,16 +7,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import React, { useState, useEffect, useRef } from 'react';
|
import React, { useState, useEffect, useRef } from 'react';
|
||||||
import {
|
import { EuiPanel, EuiText, EuiPageTemplate } from '@elastic/eui';
|
||||||
EuiPanel,
|
|
||||||
EuiPageBody,
|
|
||||||
EuiPageContent_Deprecated as EuiPageContent,
|
|
||||||
EuiPageContentBody_Deprecated as EuiPageContentBody,
|
|
||||||
EuiPageHeader,
|
|
||||||
EuiPageHeaderSection,
|
|
||||||
EuiTitle,
|
|
||||||
EuiText,
|
|
||||||
} from '@elastic/eui';
|
|
||||||
import { EuiSpacer } from '@elastic/eui';
|
import { EuiSpacer } from '@elastic/eui';
|
||||||
import { EmbeddableStart, IEmbeddable } from '@kbn/embeddable-plugin/public';
|
import { EmbeddableStart, IEmbeddable } from '@kbn/embeddable-plugin/public';
|
||||||
import {
|
import {
|
||||||
|
@ -116,16 +107,10 @@ export function EmbeddablePanelExample({ embeddableServices, searchListContainer
|
||||||
});
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<EuiPageBody>
|
<>
|
||||||
<EuiPageHeader>
|
<EuiPageTemplate.Header pageTitle="Context menu" />
|
||||||
<EuiPageHeaderSection>
|
<EuiPageTemplate.Section grow={false}>
|
||||||
<EuiTitle size="l">
|
<>
|
||||||
<h1>The embeddable panel component</h1>
|
|
||||||
</EuiTitle>
|
|
||||||
</EuiPageHeaderSection>
|
|
||||||
</EuiPageHeader>
|
|
||||||
<EuiPageContent>
|
|
||||||
<EuiPageContentBody>
|
|
||||||
<EuiText>
|
<EuiText>
|
||||||
You can render your embeddable inside the EmbeddablePanel component. This adds some
|
You can render your embeddable inside the EmbeddablePanel component. This adds some
|
||||||
extra rendering and offers a context menu with pluggable actions. Using EmbeddablePanel
|
extra rendering and offers a context menu with pluggable actions. Using EmbeddablePanel
|
||||||
|
@ -142,8 +127,8 @@ export function EmbeddablePanelExample({ embeddableServices, searchListContainer
|
||||||
</EuiPanel>
|
</EuiPanel>
|
||||||
|
|
||||||
<EuiSpacer />
|
<EuiSpacer />
|
||||||
</EuiPageContentBody>
|
</>
|
||||||
</EuiPageContent>
|
</EuiPageTemplate.Section>
|
||||||
</EuiPageBody>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,14 +8,12 @@
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import {
|
import {
|
||||||
EuiPageBody,
|
EuiPageTemplate,
|
||||||
EuiPageContent_Deprecated as EuiPageContent,
|
|
||||||
EuiPageContentBody_Deprecated as EuiPageContentBody,
|
|
||||||
EuiPageHeader,
|
|
||||||
EuiPageHeaderSection,
|
|
||||||
EuiPanel,
|
EuiPanel,
|
||||||
EuiText,
|
EuiText,
|
||||||
EuiTitle,
|
EuiTitle,
|
||||||
|
EuiCodeBlock,
|
||||||
|
EuiSpacer,
|
||||||
} from '@elastic/eui';
|
} from '@elastic/eui';
|
||||||
import { EmbeddableRenderer } from '@kbn/embeddable-plugin/public';
|
import { EmbeddableRenderer } from '@kbn/embeddable-plugin/public';
|
||||||
import {
|
import {
|
||||||
|
@ -29,40 +27,46 @@ interface Props {
|
||||||
|
|
||||||
export function HelloWorldEmbeddableExample({ helloWorldEmbeddableFactory }: Props) {
|
export function HelloWorldEmbeddableExample({ helloWorldEmbeddableFactory }: Props) {
|
||||||
return (
|
return (
|
||||||
<EuiPageBody>
|
<>
|
||||||
<EuiPageHeader>
|
<EuiPageTemplate.Header pageTitle="Render embeddable" />
|
||||||
<EuiPageHeaderSection>
|
<EuiPageTemplate.Section grow={false} bottomBorder="extended">
|
||||||
<EuiTitle size="l">
|
<>
|
||||||
<h1>Hello world example</h1>
|
<EuiTitle size="xs">
|
||||||
|
<h2>Embeddable prop</h2>
|
||||||
</EuiTitle>
|
</EuiTitle>
|
||||||
</EuiPageHeaderSection>
|
|
||||||
</EuiPageHeader>
|
|
||||||
<EuiPageContent>
|
|
||||||
<EuiPageContentBody>
|
|
||||||
<EuiText>
|
<EuiText>
|
||||||
Here the embeddable is rendered without the factory. A developer may use this method if
|
Use embeddable constructor to pass embeddable directly to{' '}
|
||||||
they want to statically embed a single embeddable into their application or page. Also
|
<strong>EmbeddableRenderer</strong>. Use <strong>input</strong> prop to declaratively
|
||||||
`input` prop may be used to declaratively update current embeddable input
|
update embeddable input.
|
||||||
</EuiText>
|
</EuiText>
|
||||||
<EuiPanel data-test-subj="helloWorldEmbeddablePanel" paddingSize="none" role="figure">
|
<EuiSpacer />
|
||||||
|
<EuiPanel data-test-subj="helloWorldEmbeddablePanel" role="figure">
|
||||||
<EmbeddableRenderer embeddable={new HelloWorldEmbeddable({ id: 'hello' })} />
|
<EmbeddableRenderer embeddable={new HelloWorldEmbeddable({ id: 'hello' })} />
|
||||||
</EuiPanel>
|
</EuiPanel>
|
||||||
|
<EuiSpacer />
|
||||||
|
<EuiCodeBlock language="jsx" fontSize="m" paddingSize="m">
|
||||||
|
{`<EmbeddableRenderer embeddable={new HelloWorldEmbeddable({ id: 'hello' })} />`}
|
||||||
|
</EuiCodeBlock>
|
||||||
|
</>
|
||||||
|
</EuiPageTemplate.Section>
|
||||||
|
<EuiPageTemplate.Section grow={false}>
|
||||||
|
<>
|
||||||
|
<EuiTitle size="xs">
|
||||||
|
<h2>Factory prop</h2>
|
||||||
|
</EuiTitle>
|
||||||
<EuiText>
|
<EuiText>
|
||||||
Here the embeddable is rendered using the factory. Internally it creates embeddable
|
Use <strong>factory</strong> prop to programatically instantiate embeddable.
|
||||||
using factory.create(). This method is used programatically when a container embeddable
|
|
||||||
attempts to initialize it's children embeddables. This method can be used when you
|
|
||||||
only have a access to a factory.
|
|
||||||
</EuiText>
|
</EuiText>
|
||||||
<EuiPanel
|
<EuiSpacer />
|
||||||
data-test-subj="helloWorldEmbeddableFromFactory"
|
<EuiPanel data-test-subj="helloWorldEmbeddableFromFactory" role="figure">
|
||||||
paddingSize="none"
|
|
||||||
role="figure"
|
|
||||||
>
|
|
||||||
<EmbeddableRenderer factory={helloWorldEmbeddableFactory} input={{ id: '1234' }} />
|
<EmbeddableRenderer factory={helloWorldEmbeddableFactory} input={{ id: '1234' }} />
|
||||||
</EuiPanel>
|
</EuiPanel>
|
||||||
</EuiPageContentBody>
|
<EuiSpacer />
|
||||||
</EuiPageContent>
|
<EuiCodeBlock language="jsx" fontSize="m" paddingSize="m">
|
||||||
</EuiPageBody>
|
{`<EmbeddableRenderer factory={helloWorldEmbeddableFactory} input={{ id: '1234' }} />`}
|
||||||
|
</EuiCodeBlock>
|
||||||
|
</>
|
||||||
|
</EuiPageTemplate.Section>
|
||||||
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,41 +7,69 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import {
|
import { EuiPanel, EuiSpacer, EuiText, EuiPageTemplate, EuiCodeBlock } from '@elastic/eui';
|
||||||
EuiPageBody,
|
|
||||||
EuiPageContent_Deprecated as EuiPageContent,
|
|
||||||
EuiPageContentBody_Deprecated as EuiPageContentBody,
|
|
||||||
EuiPageHeader,
|
|
||||||
EuiPageHeaderSection,
|
|
||||||
EuiPanel,
|
|
||||||
EuiSpacer,
|
|
||||||
EuiText,
|
|
||||||
EuiTitle,
|
|
||||||
} from '@elastic/eui';
|
|
||||||
import { EmbeddableRenderer, ViewMode } from '@kbn/embeddable-plugin/public';
|
import { EmbeddableRenderer, ViewMode } from '@kbn/embeddable-plugin/public';
|
||||||
import {
|
import {
|
||||||
HELLO_WORLD_EMBEDDABLE,
|
HELLO_WORLD_EMBEDDABLE,
|
||||||
MULTI_TASK_TODO_EMBEDDABLE,
|
|
||||||
TODO_EMBEDDABLE,
|
TODO_EMBEDDABLE,
|
||||||
ListContainerFactory,
|
ListContainerFactory,
|
||||||
SearchableListContainerFactory,
|
|
||||||
} from '@kbn/embeddable-examples-plugin/public';
|
} from '@kbn/embeddable-examples-plugin/public';
|
||||||
import { SearchableContainerInput } from '@kbn/embeddable-examples-plugin/public/searchable_list_container/searchable_list_container';
|
|
||||||
import { TodoInput } from '@kbn/embeddable-examples-plugin/public/todo';
|
import { TodoInput } from '@kbn/embeddable-examples-plugin/public/todo';
|
||||||
import { MultiTaskTodoInput } from '@kbn/embeddable-examples-plugin/public/multi_task_todo';
|
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
listContainerEmbeddableFactory: ListContainerFactory;
|
listContainerEmbeddableFactory: ListContainerFactory;
|
||||||
searchableListContainerEmbeddableFactory: SearchableListContainerFactory;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function ListContainerExample({
|
export function ListContainerExample({ listContainerEmbeddableFactory }: Props) {
|
||||||
listContainerEmbeddableFactory,
|
return (
|
||||||
searchableListContainerEmbeddableFactory,
|
<>
|
||||||
}: Props) {
|
<EuiPageTemplate.Header pageTitle="Groups of embeddables" />
|
||||||
const listInput: SearchableContainerInput = {
|
<EuiPageTemplate.Section grow={false}>
|
||||||
|
<>
|
||||||
|
<EuiText>Use container embeddable to render a group of embeddables.</EuiText>
|
||||||
|
<EuiSpacer />
|
||||||
|
<EuiPanel data-test-subj="listContainerEmbeddablePanel" paddingSize="none" role="figure">
|
||||||
|
<EmbeddableRenderer
|
||||||
|
factory={listContainerEmbeddableFactory}
|
||||||
|
input={{
|
||||||
|
id: 'hello',
|
||||||
|
title: 'Todo list',
|
||||||
|
viewMode: ViewMode.VIEW,
|
||||||
|
panels: {
|
||||||
|
'1': {
|
||||||
|
type: HELLO_WORLD_EMBEDDABLE,
|
||||||
|
explicitInput: {
|
||||||
|
id: '1',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'2': {
|
||||||
|
type: TODO_EMBEDDABLE,
|
||||||
|
explicitInput: {
|
||||||
|
id: '2',
|
||||||
|
task: 'Goes out on Wednesdays!',
|
||||||
|
icon: 'broom',
|
||||||
|
title: 'Take out the trash',
|
||||||
|
} as TodoInput,
|
||||||
|
},
|
||||||
|
'3': {
|
||||||
|
type: TODO_EMBEDDABLE,
|
||||||
|
explicitInput: {
|
||||||
|
id: '3',
|
||||||
|
icon: 'broom',
|
||||||
|
title: 'Vaccum the floor',
|
||||||
|
} as TodoInput,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</EuiPanel>
|
||||||
|
<EuiSpacer />
|
||||||
|
<EuiCodeBlock language="jsx" fontSize="m" paddingSize="m">
|
||||||
|
{`<EmbeddableRenderer
|
||||||
|
factory={listContainerEmbeddableFactory}
|
||||||
|
input={{
|
||||||
id: 'hello',
|
id: 'hello',
|
||||||
title: 'My todo list',
|
title: 'Todo list',
|
||||||
viewMode: ViewMode.VIEW,
|
viewMode: ViewMode.VIEW,
|
||||||
panels: {
|
panels: {
|
||||||
'1': {
|
'1': {
|
||||||
|
@ -68,110 +96,11 @@ export function ListContainerExample({
|
||||||
} as TodoInput,
|
} as TodoInput,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
}}
|
||||||
|
/>`}
|
||||||
const searchableInput: SearchableContainerInput = {
|
</EuiCodeBlock>
|
||||||
id: '1',
|
</>
|
||||||
title: 'My searchable todo list',
|
</EuiPageTemplate.Section>
|
||||||
viewMode: ViewMode.VIEW,
|
</>
|
||||||
panels: {
|
|
||||||
'1': {
|
|
||||||
type: HELLO_WORLD_EMBEDDABLE,
|
|
||||||
explicitInput: {
|
|
||||||
id: '1',
|
|
||||||
title: 'Hello',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
'2': {
|
|
||||||
type: TODO_EMBEDDABLE,
|
|
||||||
explicitInput: {
|
|
||||||
id: '2',
|
|
||||||
task: 'Goes out on Wednesdays!',
|
|
||||||
icon: 'broom',
|
|
||||||
title: 'Take out the trash',
|
|
||||||
} as TodoInput,
|
|
||||||
},
|
|
||||||
'3': {
|
|
||||||
type: MULTI_TASK_TODO_EMBEDDABLE,
|
|
||||||
explicitInput: {
|
|
||||||
id: '3',
|
|
||||||
icon: 'searchProfilerApp',
|
|
||||||
title: 'Learn more',
|
|
||||||
tasks: ['Go to school', 'Watch planet earth', 'Read the encyclopedia'],
|
|
||||||
} as MultiTaskTodoInput,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<EuiPageBody>
|
|
||||||
<EuiPageHeader>
|
|
||||||
<EuiPageHeaderSection>
|
|
||||||
<EuiTitle size="l">
|
|
||||||
<h1>List container example</h1>
|
|
||||||
</EuiTitle>
|
|
||||||
</EuiPageHeaderSection>
|
|
||||||
</EuiPageHeader>
|
|
||||||
<EuiPageContent>
|
|
||||||
<EuiPageContentBody>
|
|
||||||
<EuiText>
|
|
||||||
Here is a container embeddable that contains other embeddables and displays them in a
|
|
||||||
list.
|
|
||||||
</EuiText>
|
|
||||||
<EuiPanel data-test-subj="listContainerEmbeddablePanel" paddingSize="none" role="figure">
|
|
||||||
<EmbeddableRenderer input={listInput} factory={listContainerEmbeddableFactory} />
|
|
||||||
</EuiPanel>
|
|
||||||
|
|
||||||
<EuiSpacer />
|
|
||||||
<EuiText>
|
|
||||||
<p>
|
|
||||||
The reason to use a container embeddable instead of just a custom react component is
|
|
||||||
because it comes with helpful methods to store the state of all its children
|
|
||||||
embeddables, listeners to clean up the input state when an embeddable is added or
|
|
||||||
removed, and a way to pass down the container embeddable's own input to its
|
|
||||||
children. In the above example, the container did not take any input. Let's modify
|
|
||||||
it so it does.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
In this Searchable List Container, the container takes in a search string as input and
|
|
||||||
passes that down to all its children. It also listens to its children that output
|
|
||||||
`hasMatch`, and removes them from the list when there is a search string and the child
|
|
||||||
doesn't match.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
The first HelloWorldEmbeddable does not emit the hasMatch output variable, so the
|
|
||||||
container chooses to hide it.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
Check out the "Dynamically adding children" section, to see how to add
|
|
||||||
children to this container, and see it rendered inside an `EmbeddablePanel` component.
|
|
||||||
</p>
|
|
||||||
</EuiText>
|
|
||||||
|
|
||||||
<EuiSpacer />
|
|
||||||
<EuiPanel
|
|
||||||
data-test-subj="searchableListContainerEmbeddablePanel"
|
|
||||||
paddingSize="none"
|
|
||||||
role="figure"
|
|
||||||
>
|
|
||||||
<EmbeddableRenderer
|
|
||||||
input={searchableInput}
|
|
||||||
factory={searchableListContainerEmbeddableFactory}
|
|
||||||
/>{' '}
|
|
||||||
</EuiPanel>
|
|
||||||
<EuiSpacer />
|
|
||||||
<EuiText>
|
|
||||||
<p>
|
|
||||||
There currently is no formal way to limit what children can be added to a container.
|
|
||||||
If the use case arose, it wouldn't be difficult. In the mean time, it's good
|
|
||||||
to understand that children may ignore input they don't care about. Likewise the
|
|
||||||
container will have to choose what to do when it encounters children that are missing
|
|
||||||
certain output variables.
|
|
||||||
</p>
|
|
||||||
</EuiText>
|
|
||||||
</EuiPageContentBody>
|
|
||||||
</EuiPageContent>
|
|
||||||
</EuiPageBody>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,22 +8,17 @@
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import {
|
import {
|
||||||
EuiButton,
|
EuiCodeBlock,
|
||||||
EuiFieldText,
|
EuiFieldText,
|
||||||
EuiFlexGroup,
|
EuiForm,
|
||||||
EuiFlexItem,
|
|
||||||
EuiFormRow,
|
EuiFormRow,
|
||||||
EuiPageBody,
|
|
||||||
EuiPageContent_Deprecated as EuiPageContent,
|
|
||||||
EuiPageContentBody_Deprecated as EuiPageContentBody,
|
|
||||||
EuiPageHeader,
|
|
||||||
EuiPageHeaderSection,
|
|
||||||
EuiPanel,
|
EuiPanel,
|
||||||
EuiText,
|
EuiText,
|
||||||
EuiTextArea,
|
EuiTextArea,
|
||||||
EuiTitle,
|
EuiPageTemplate,
|
||||||
|
EuiSpacer,
|
||||||
|
EuiSelect,
|
||||||
} from '@elastic/eui';
|
} from '@elastic/eui';
|
||||||
import { TodoInput } from '@kbn/embeddable-examples-plugin/public/todo';
|
|
||||||
import { TodoEmbeddableFactory } from '@kbn/embeddable-examples-plugin/public';
|
import { TodoEmbeddableFactory } from '@kbn/embeddable-examples-plugin/public';
|
||||||
import { EmbeddableRenderer } from '@kbn/embeddable-plugin/public';
|
import { EmbeddableRenderer } from '@kbn/embeddable-plugin/public';
|
||||||
|
|
||||||
|
@ -32,96 +27,94 @@ interface Props {
|
||||||
}
|
}
|
||||||
|
|
||||||
interface State {
|
interface State {
|
||||||
task?: string;
|
task: string;
|
||||||
title?: string;
|
title: string;
|
||||||
icon?: string;
|
icon: string;
|
||||||
loading: boolean;
|
|
||||||
input: TodoInput;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const ICON_OPTIONS = [
|
||||||
|
{ value: 'beaker', text: 'beaker' },
|
||||||
|
{ value: 'bell', text: 'bell' },
|
||||||
|
{ value: 'bolt', text: 'bolt' },
|
||||||
|
{ value: 'broom', text: 'broom' },
|
||||||
|
{ value: 'bug', text: 'bug' },
|
||||||
|
{ value: 'bullseye', text: 'bullseye' },
|
||||||
|
];
|
||||||
|
|
||||||
export class TodoEmbeddableExample extends React.Component<Props, State> {
|
export class TodoEmbeddableExample extends React.Component<Props, State> {
|
||||||
constructor(props: Props) {
|
constructor(props: Props) {
|
||||||
super(props);
|
super(props);
|
||||||
|
|
||||||
this.state = {
|
this.state = {
|
||||||
loading: true,
|
icon: 'broom',
|
||||||
input: {
|
task: 'Take out the trash',
|
||||||
id: '1',
|
title: 'Trash',
|
||||||
task: 'Take out the trash',
|
|
||||||
icon: 'broom',
|
|
||||||
title: 'Trash',
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private onUpdateEmbeddableInput = () => {
|
|
||||||
const { task, title, icon, input } = this.state;
|
|
||||||
this.setState({ input: { ...input, task: task ?? '', title, icon } });
|
|
||||||
};
|
|
||||||
|
|
||||||
public render() {
|
public render() {
|
||||||
return (
|
return (
|
||||||
<EuiPageBody>
|
<>
|
||||||
<EuiPageHeader>
|
<EuiPageTemplate.Header pageTitle="Update embeddable state" />
|
||||||
<EuiPageHeaderSection>
|
<EuiPageTemplate.Section grow={false}>
|
||||||
<EuiTitle size="l">
|
<>
|
||||||
<h1>Todo example</h1>
|
|
||||||
</EuiTitle>
|
|
||||||
</EuiPageHeaderSection>
|
|
||||||
</EuiPageHeader>
|
|
||||||
<EuiPageContent>
|
|
||||||
<EuiPageContentBody>
|
|
||||||
<EuiText>
|
<EuiText>
|
||||||
This embeddable takes input parameters, task, title and icon. You can update them
|
Use <strong>input</strong> prop to update embeddable state.
|
||||||
using this form. Input changes will be passed inside `EmbeddableRenderer` as a prop
|
|
||||||
</EuiText>
|
</EuiText>
|
||||||
<EuiFlexGroup>
|
<EuiSpacer />
|
||||||
<EuiFlexItem grow={true}>
|
<EuiForm>
|
||||||
<EuiFormRow label="Title">
|
<EuiFormRow label="Title">
|
||||||
<EuiFieldText
|
<EuiFieldText
|
||||||
data-test-subj="titleTodo"
|
data-test-subj="titleTodo"
|
||||||
onChange={(ev) => this.setState({ title: ev.target.value })}
|
value={this.state.title}
|
||||||
/>
|
onChange={(ev) => this.setState({ title: ev.target.value })}
|
||||||
</EuiFormRow>
|
/>
|
||||||
</EuiFlexItem>
|
</EuiFormRow>
|
||||||
<EuiFlexItem grow={true}>
|
<EuiFormRow label="Icon">
|
||||||
<EuiFormRow label="Icon">
|
<EuiSelect
|
||||||
<EuiFieldText
|
data-test-subj="iconTodo"
|
||||||
data-test-subj="iconTodo"
|
value={this.state.icon}
|
||||||
onChange={(ev) => this.setState({ icon: ev.target.value })}
|
options={ICON_OPTIONS}
|
||||||
/>
|
onChange={(ev) => this.setState({ icon: ev.target.value })}
|
||||||
</EuiFormRow>
|
/>
|
||||||
</EuiFlexItem>
|
</EuiFormRow>
|
||||||
<EuiFlexItem>
|
<EuiFormRow label="Task">
|
||||||
<EuiFormRow label="Task">
|
<EuiTextArea
|
||||||
<EuiTextArea
|
fullWidth
|
||||||
fullWidth
|
resize="horizontal"
|
||||||
resize="horizontal"
|
data-test-subj="taskTodo"
|
||||||
data-test-subj="taskTodo"
|
value={this.state.task}
|
||||||
onChange={(ev) => this.setState({ task: ev.target.value })}
|
onChange={(ev) => this.setState({ task: ev.target.value })}
|
||||||
/>
|
/>
|
||||||
</EuiFormRow>
|
</EuiFormRow>
|
||||||
</EuiFlexItem>
|
</EuiForm>
|
||||||
<EuiFlexItem grow={false}>
|
<EuiSpacer />
|
||||||
<EuiFormRow hasEmptyLabelSpace>
|
<EuiPanel data-test-subj="todoEmbeddable" role="figure">
|
||||||
<EuiButton
|
|
||||||
data-test-subj="updateTodoButton"
|
|
||||||
onClick={this.onUpdateEmbeddableInput}
|
|
||||||
>
|
|
||||||
Update
|
|
||||||
</EuiButton>
|
|
||||||
</EuiFormRow>
|
|
||||||
</EuiFlexItem>
|
|
||||||
</EuiFlexGroup>
|
|
||||||
<EuiPanel data-test-subj="todoEmbeddable" paddingSize="none" role="figure">
|
|
||||||
<EmbeddableRenderer
|
<EmbeddableRenderer
|
||||||
factory={this.props.todoEmbeddableFactory}
|
factory={this.props.todoEmbeddableFactory}
|
||||||
input={this.state.input}
|
input={{
|
||||||
|
id: '1',
|
||||||
|
task: this.state.task,
|
||||||
|
title: this.state.title,
|
||||||
|
icon: this.state.icon,
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
</EuiPanel>
|
</EuiPanel>
|
||||||
</EuiPageContentBody>
|
<EuiSpacer />
|
||||||
</EuiPageContent>
|
<EuiCodeBlock language="jsx" fontSize="m" paddingSize="m">
|
||||||
</EuiPageBody>
|
{`<EmbeddableRenderer
|
||||||
|
factory={this.props.todoEmbeddableFactory}
|
||||||
|
input={{
|
||||||
|
id: '1',
|
||||||
|
task: this.state.task,
|
||||||
|
title: this.state.title,
|
||||||
|
icon: this.state.icon,
|
||||||
|
}}
|
||||||
|
/>`}
|
||||||
|
</EuiCodeBlock>
|
||||||
|
</>
|
||||||
|
</EuiPageTemplate.Section>
|
||||||
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,36 +22,14 @@ export default function ({ getService }: PluginFunctionalProviderContext) {
|
||||||
it('list containers render', async () => {
|
it('list containers render', async () => {
|
||||||
await retry.try(async () => {
|
await retry.try(async () => {
|
||||||
const title = await testSubjects.getVisibleText('listContainerTitle');
|
const title = await testSubjects.getVisibleText('listContainerTitle');
|
||||||
expect(title).to.be('My todo list');
|
expect(title).to.be('Todo list');
|
||||||
|
|
||||||
const titles = await testSubjects.getVisibleTextAll('todoEmbeddableTitle');
|
const titles = await testSubjects.getVisibleTextAll('todoEmbeddableTitle');
|
||||||
expect(titles).to.eql(['Take out the trash', 'Vaccum the floor', 'Take out the trash']);
|
expect(titles).to.eql(['Take out the trash', 'Vaccum the floor']);
|
||||||
|
|
||||||
const searchableTitle = await testSubjects.getVisibleText('searchableListContainerTitle');
|
|
||||||
expect(searchableTitle).to.be('My searchable todo list');
|
|
||||||
|
|
||||||
const text = await testSubjects.getVisibleTextAll('helloWorldEmbeddable');
|
const text = await testSubjects.getVisibleTextAll('helloWorldEmbeddable');
|
||||||
expect(text).to.eql(['HELLO WORLD!', 'HELLO WORLD!']);
|
expect(text).to.eql(['HELLO WORLD!']);
|
||||||
|
|
||||||
const tasks = await testSubjects.getVisibleTextAll('multiTaskTodoTask');
|
|
||||||
expect(tasks).to.eql(['Go to school', 'Watch planet earth', 'Read the encyclopedia']);
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('searchable container deletes children', async () => {
|
|
||||||
await testSubjects.click('todoCheckBox-1');
|
|
||||||
await testSubjects.click('deleteCheckedTodos');
|
|
||||||
|
|
||||||
const text = await testSubjects.getVisibleTextAll('helloWorldEmbeddable');
|
|
||||||
expect(text).to.eql(['HELLO WORLD!']);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('searchable container finds matches in multi-task children', async () => {
|
|
||||||
await testSubjects.setValue('filterTodos', 'earth');
|
|
||||||
await testSubjects.click('checkMatchingTodos');
|
|
||||||
await testSubjects.click('deleteCheckedTodos');
|
|
||||||
|
|
||||||
await testSubjects.missingOrFail('multiTaskTodoTask');
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,7 +31,6 @@ export default function ({ getService }: PluginFunctionalProviderContext) {
|
||||||
it('todo embeddable updates', async () => {
|
it('todo embeddable updates', async () => {
|
||||||
await testSubjects.setValue('taskTodo', 'read a book');
|
await testSubjects.setValue('taskTodo', 'read a book');
|
||||||
await testSubjects.setValue('titleTodo', 'Learn');
|
await testSubjects.setValue('titleTodo', 'Learn');
|
||||||
await testSubjects.click('updateTodoButton');
|
|
||||||
|
|
||||||
await retry.try(async () => {
|
await retry.try(async () => {
|
||||||
const title = await testSubjects.getVisibleText('todoEmbeddableTitle');
|
const title = await testSubjects.getVisibleText('todoEmbeddableTitle');
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue