mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 17:28:26 -04:00
Unifying converting listing pages to new layout (#98651)
Co-authored-by: Caroline Horn <549577+cchaos@users.noreply.github.com> Co-authored-by: cchaos <caroline.horn@elastic.co> Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
parent
238fc3ac1d
commit
921c942bef
18 changed files with 1049 additions and 656 deletions
BIN
dev_docs/assets/kibana_custom_empty_state.png
Normal file
BIN
dev_docs/assets/kibana_custom_empty_state.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 124 KiB |
BIN
dev_docs/assets/kibana_default_empty_state.png
Normal file
BIN
dev_docs/assets/kibana_default_empty_state.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 130 KiB |
BIN
dev_docs/assets/kibana_header_and_empty_state.png
Normal file
BIN
dev_docs/assets/kibana_header_and_empty_state.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 124 KiB |
|
@ -70,6 +70,14 @@ Check out the Map Embeddable if you wish to embed a map in your application.
|
|||
|
||||
**Github labels**: `Team:Geo`
|
||||
|
||||
### KibanaPageTemplate
|
||||
|
||||
All Kibana pages should use KibanaPageTemplate to setup their pages. It's a thin wrapper around [EuiPageTemplate](https://elastic.github.io/eui/#/layout/page) that makes setting up common types of Kibana pages quicker and easier while also adhering to any Kibana-specific requirements.
|
||||
|
||||
Check out <DocLink id="kibDevDocsKBTTutorial" text="the KibanaPageTemplate tutorial" /> for more implementation guidance.
|
||||
|
||||
**Github labels**: `EUI`
|
||||
|
||||
## Searching
|
||||
|
||||
### Index Patterns
|
||||
|
|
86
dev_docs/tutorials/kibana_page_template.mdx
Normal file
86
dev_docs/tutorials/kibana_page_template.mdx
Normal file
|
@ -0,0 +1,86 @@
|
|||
---
|
||||
id: kibDevDocsKBLTutorial
|
||||
slug: /kibana-dev-docs/tutorials/kibana-page-layout
|
||||
title: KibanaPageLayout component
|
||||
summary: Learn how to create pages in Kibana
|
||||
date: 2021-03-20
|
||||
tags: ['kibana', 'dev', 'ui', 'tutorials']
|
||||
---
|
||||
|
||||
`KibanaPageLayout` is a thin wrapper around [EuiPageTemplate](https://elastic.github.io/eui/#/layout/page) that makes setting up common types of Kibana pages quicker and easier while also adhering to any Kibana-specific requirements and patterns.
|
||||
|
||||
Refer to EUI's documentation on [EuiPageTemplate](https://elastic.github.io/eui/#/layout/page) for constructing page layouts.
|
||||
|
||||
## `isEmptyState`
|
||||
|
||||
Use the `isEmptyState` prop for when there is no page content to show. For example, before the user has created something, when no search results are found, before data is populated, or when permissions aren't met.
|
||||
|
||||
The default empty state uses any `pageHeader` info provided to populate an [`EuiEmptyPrompt`](https://elastic.github.io/eui/#/display/empty-prompt) and uses the `centeredBody` template type.
|
||||
|
||||
```tsx
|
||||
<KibanaPageLayout
|
||||
isEmptyState={true}
|
||||
pageHeader={{
|
||||
iconType: 'dashboardApp',
|
||||
pageTitle: 'Dashboards',
|
||||
description: "You don't have any dashboards yet.",
|
||||
rightSideItems: [
|
||||
<EuiButton fill iconType="plusInCircleFilled">
|
||||
Create new dashboard
|
||||
</EuiButton>,
|
||||
],
|
||||
}}
|
||||
/>
|
||||
```
|
||||
|
||||

|
||||
|
||||
<DocCallOut color="warning" title="Missing page header content can lead to an anemic empty state">
|
||||
Because all properties of the page header are optional, the empty state has the potential to
|
||||
render blank. Make sure your empty state doesn't leave the user confused.
|
||||
</DocCallOut>
|
||||
|
||||
### Custom empty state
|
||||
|
||||
You can also provide a custom empty prompt to replace the pre-built one. You'll want to remove any `pageHeader` props and pass an [`EuiEmptyPrompt`](https://elastic.github.io/eui/#/display/empty-prompt) directly as the child of KibanaPageLayout.
|
||||
|
||||
```tsx
|
||||
<KibanaPageLayout isEmptyState={true}>
|
||||
<EuiEmptyPrompt
|
||||
title={<h1>No data</h1>}
|
||||
body="You have no data. Would you like some of ours?"
|
||||
actions={[
|
||||
<EuiButton fill iconType="plusInCircleFilled">
|
||||
Get sample data
|
||||
</EuiButton>,
|
||||
]}
|
||||
/>
|
||||
</KibanaPageLayout>
|
||||
```
|
||||
|
||||

|
||||
|
||||
### Empty states with a page header
|
||||
|
||||
When passing both a `pageHeader` configuration and `isEmptyState`, the component will render the proper template (`centeredContent`). Be sure to reduce the heading level within your child empty prompt to `<h2>`.
|
||||
|
||||
```tsx
|
||||
<KibanaPageLayout
|
||||
isEmptyState={true}
|
||||
pageHeader={{
|
||||
pageTitle: 'Dashboards',
|
||||
}}
|
||||
>
|
||||
<EuiEmptyPrompt
|
||||
title={<h2>No data</h2>}
|
||||
body="You have no data. Would you like some of ours?"
|
||||
actions={[
|
||||
<EuiButton fill iconType="plusInCircleFilled">
|
||||
Get sample data
|
||||
</EuiButton>,
|
||||
]}
|
||||
/>
|
||||
</KibanaPageLayout>
|
||||
```
|
||||
|
||||

|
|
@ -25,6 +25,66 @@ exports[`after fetch When given a title that matches multiple dashboards, filter
|
|||
createItem={[Function]}
|
||||
deleteItems={[Function]}
|
||||
editItem={[Function]}
|
||||
emptyPrompt={
|
||||
<EuiEmptyPrompt
|
||||
actions={
|
||||
<EuiButton
|
||||
data-test-subj="createDashboardPromptButton"
|
||||
fill={true}
|
||||
iconType="plusInCircle"
|
||||
onClick={[Function]}
|
||||
>
|
||||
<FormattedMessage
|
||||
defaultMessage="Create new dashboard"
|
||||
id="dashboard.listing.createNewDashboard.createButtonLabel"
|
||||
values={Object {}}
|
||||
/>
|
||||
</EuiButton>
|
||||
}
|
||||
body={
|
||||
<React.Fragment>
|
||||
<p>
|
||||
<FormattedMessage
|
||||
defaultMessage="You can combine data views from any Kibana app into one dashboard and see everything in one place."
|
||||
id="dashboard.listing.createNewDashboard.combineDataViewFromKibanaAppDescription"
|
||||
values={Object {}}
|
||||
/>
|
||||
</p>
|
||||
<p>
|
||||
<FormattedMessage
|
||||
defaultMessage="New to Kibana? {sampleDataInstallLink} to take a test drive."
|
||||
id="dashboard.listing.createNewDashboard.newToKibanaDescription"
|
||||
values={
|
||||
Object {
|
||||
"sampleDataInstallLink": <EuiLink
|
||||
onClick={[Function]}
|
||||
>
|
||||
<FormattedMessage
|
||||
defaultMessage="Install some sample data"
|
||||
id="dashboard.listing.createNewDashboard.sampleDataInstallLinkText"
|
||||
values={Object {}}
|
||||
/>
|
||||
</EuiLink>,
|
||||
}
|
||||
}
|
||||
/>
|
||||
</p>
|
||||
</React.Fragment>
|
||||
}
|
||||
iconType="dashboardApp"
|
||||
title={
|
||||
<h1
|
||||
id="dashboardListingHeading"
|
||||
>
|
||||
<FormattedMessage
|
||||
defaultMessage="Create your first dashboard"
|
||||
id="dashboard.listing.createNewDashboard.title"
|
||||
values={Object {}}
|
||||
/>
|
||||
</h1>
|
||||
}
|
||||
/>
|
||||
}
|
||||
entityName="dashboard"
|
||||
entityNamePlural="dashboards"
|
||||
findItems={[Function]}
|
||||
|
@ -32,68 +92,6 @@ exports[`after fetch When given a title that matches multiple dashboards, filter
|
|||
initialFilter="\\"search by title\\""
|
||||
initialPageSize={20}
|
||||
listingLimit={100}
|
||||
noItemsFragment={
|
||||
<div>
|
||||
<EuiEmptyPrompt
|
||||
actions={
|
||||
<EuiButton
|
||||
data-test-subj="createDashboardPromptButton"
|
||||
fill={true}
|
||||
iconType="plusInCircle"
|
||||
onClick={[Function]}
|
||||
>
|
||||
<FormattedMessage
|
||||
defaultMessage="Create new dashboard"
|
||||
id="dashboard.listing.createNewDashboard.createButtonLabel"
|
||||
values={Object {}}
|
||||
/>
|
||||
</EuiButton>
|
||||
}
|
||||
body={
|
||||
<React.Fragment>
|
||||
<p>
|
||||
<FormattedMessage
|
||||
defaultMessage="You can combine data views from any Kibana app into one dashboard and see everything in one place."
|
||||
id="dashboard.listing.createNewDashboard.combineDataViewFromKibanaAppDescription"
|
||||
values={Object {}}
|
||||
/>
|
||||
</p>
|
||||
<p>
|
||||
<FormattedMessage
|
||||
defaultMessage="New to Kibana? {sampleDataInstallLink} to take a test drive."
|
||||
id="dashboard.listing.createNewDashboard.newToKibanaDescription"
|
||||
values={
|
||||
Object {
|
||||
"sampleDataInstallLink": <EuiLink
|
||||
onClick={[Function]}
|
||||
>
|
||||
<FormattedMessage
|
||||
defaultMessage="Install some sample data"
|
||||
id="dashboard.listing.createNewDashboard.sampleDataInstallLinkText"
|
||||
values={Object {}}
|
||||
/>
|
||||
</EuiLink>,
|
||||
}
|
||||
}
|
||||
/>
|
||||
</p>
|
||||
</React.Fragment>
|
||||
}
|
||||
iconType="dashboardApp"
|
||||
title={
|
||||
<h1
|
||||
id="dashboardListingHeading"
|
||||
>
|
||||
<FormattedMessage
|
||||
defaultMessage="Create your first dashboard"
|
||||
id="dashboard.listing.createNewDashboard.title"
|
||||
values={Object {}}
|
||||
/>
|
||||
</h1>
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
}
|
||||
rowHeader="title"
|
||||
searchFilters={Array []}
|
||||
tableCaption="Dashboards"
|
||||
|
@ -126,24 +124,7 @@ exports[`after fetch When given a title that matches multiple dashboards, filter
|
|||
"remove": [MockFunction],
|
||||
}
|
||||
}
|
||||
>
|
||||
<EuiPage
|
||||
className="itemListing__page"
|
||||
data-test-subj="dashboardLandingPage"
|
||||
restrictWidth={true}
|
||||
>
|
||||
<div
|
||||
className="euiPage euiPage--paddingMedium euiPage--grow euiPage--restrictWidth-default itemListing__page"
|
||||
data-test-subj="dashboardLandingPage"
|
||||
>
|
||||
<EuiPageBody>
|
||||
<main
|
||||
className="euiPageBody euiPageBody--borderRadiusNone"
|
||||
/>
|
||||
</EuiPageBody>
|
||||
</div>
|
||||
</EuiPage>
|
||||
</TableListView>
|
||||
/>
|
||||
</DashboardListing>
|
||||
`;
|
||||
|
||||
|
@ -168,6 +149,22 @@ exports[`after fetch hideWriteControls 1`] = `
|
|||
redirectTo={[MockFunction]}
|
||||
>
|
||||
<TableListView
|
||||
emptyPrompt={
|
||||
<EuiEmptyPrompt
|
||||
iconType="dashboardApp"
|
||||
title={
|
||||
<h1
|
||||
id="dashboardListingHeading"
|
||||
>
|
||||
<FormattedMessage
|
||||
defaultMessage="Looks like you don't have any dashboards."
|
||||
id="dashboard.listing.noItemsMessage"
|
||||
values={Object {}}
|
||||
/>
|
||||
</h1>
|
||||
}
|
||||
/>
|
||||
}
|
||||
entityName="dashboard"
|
||||
entityNamePlural="dashboards"
|
||||
findItems={[Function]}
|
||||
|
@ -175,24 +172,6 @@ exports[`after fetch hideWriteControls 1`] = `
|
|||
initialFilter=""
|
||||
initialPageSize={20}
|
||||
listingLimit={100}
|
||||
noItemsFragment={
|
||||
<div>
|
||||
<EuiEmptyPrompt
|
||||
iconType="dashboardApp"
|
||||
title={
|
||||
<h1
|
||||
id="dashboardListingHeading"
|
||||
>
|
||||
<FormattedMessage
|
||||
defaultMessage="Looks like you don't have any dashboards."
|
||||
id="dashboard.listing.noItemsMessage"
|
||||
values={Object {}}
|
||||
/>
|
||||
</h1>
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
}
|
||||
rowHeader="title"
|
||||
searchFilters={Array []}
|
||||
tableCaption="Dashboards"
|
||||
|
@ -225,24 +204,7 @@ exports[`after fetch hideWriteControls 1`] = `
|
|||
"remove": [MockFunction],
|
||||
}
|
||||
}
|
||||
>
|
||||
<EuiPage
|
||||
className="itemListing__page"
|
||||
data-test-subj="dashboardLandingPage"
|
||||
restrictWidth={true}
|
||||
>
|
||||
<div
|
||||
className="euiPage euiPage--paddingMedium euiPage--grow euiPage--restrictWidth-default itemListing__page"
|
||||
data-test-subj="dashboardLandingPage"
|
||||
>
|
||||
<EuiPageBody>
|
||||
<main
|
||||
className="euiPageBody euiPageBody--borderRadiusNone"
|
||||
/>
|
||||
</EuiPageBody>
|
||||
</div>
|
||||
</EuiPage>
|
||||
</TableListView>
|
||||
/>
|
||||
</DashboardListing>
|
||||
`;
|
||||
|
||||
|
@ -271,6 +233,66 @@ exports[`after fetch initialFilter 1`] = `
|
|||
createItem={[Function]}
|
||||
deleteItems={[Function]}
|
||||
editItem={[Function]}
|
||||
emptyPrompt={
|
||||
<EuiEmptyPrompt
|
||||
actions={
|
||||
<EuiButton
|
||||
data-test-subj="createDashboardPromptButton"
|
||||
fill={true}
|
||||
iconType="plusInCircle"
|
||||
onClick={[Function]}
|
||||
>
|
||||
<FormattedMessage
|
||||
defaultMessage="Create new dashboard"
|
||||
id="dashboard.listing.createNewDashboard.createButtonLabel"
|
||||
values={Object {}}
|
||||
/>
|
||||
</EuiButton>
|
||||
}
|
||||
body={
|
||||
<React.Fragment>
|
||||
<p>
|
||||
<FormattedMessage
|
||||
defaultMessage="You can combine data views from any Kibana app into one dashboard and see everything in one place."
|
||||
id="dashboard.listing.createNewDashboard.combineDataViewFromKibanaAppDescription"
|
||||
values={Object {}}
|
||||
/>
|
||||
</p>
|
||||
<p>
|
||||
<FormattedMessage
|
||||
defaultMessage="New to Kibana? {sampleDataInstallLink} to take a test drive."
|
||||
id="dashboard.listing.createNewDashboard.newToKibanaDescription"
|
||||
values={
|
||||
Object {
|
||||
"sampleDataInstallLink": <EuiLink
|
||||
onClick={[Function]}
|
||||
>
|
||||
<FormattedMessage
|
||||
defaultMessage="Install some sample data"
|
||||
id="dashboard.listing.createNewDashboard.sampleDataInstallLinkText"
|
||||
values={Object {}}
|
||||
/>
|
||||
</EuiLink>,
|
||||
}
|
||||
}
|
||||
/>
|
||||
</p>
|
||||
</React.Fragment>
|
||||
}
|
||||
iconType="dashboardApp"
|
||||
title={
|
||||
<h1
|
||||
id="dashboardListingHeading"
|
||||
>
|
||||
<FormattedMessage
|
||||
defaultMessage="Create your first dashboard"
|
||||
id="dashboard.listing.createNewDashboard.title"
|
||||
values={Object {}}
|
||||
/>
|
||||
</h1>
|
||||
}
|
||||
/>
|
||||
}
|
||||
entityName="dashboard"
|
||||
entityNamePlural="dashboards"
|
||||
findItems={[Function]}
|
||||
|
@ -278,68 +300,6 @@ exports[`after fetch initialFilter 1`] = `
|
|||
initialFilter="testFilter"
|
||||
initialPageSize={20}
|
||||
listingLimit={100}
|
||||
noItemsFragment={
|
||||
<div>
|
||||
<EuiEmptyPrompt
|
||||
actions={
|
||||
<EuiButton
|
||||
data-test-subj="createDashboardPromptButton"
|
||||
fill={true}
|
||||
iconType="plusInCircle"
|
||||
onClick={[Function]}
|
||||
>
|
||||
<FormattedMessage
|
||||
defaultMessage="Create new dashboard"
|
||||
id="dashboard.listing.createNewDashboard.createButtonLabel"
|
||||
values={Object {}}
|
||||
/>
|
||||
</EuiButton>
|
||||
}
|
||||
body={
|
||||
<React.Fragment>
|
||||
<p>
|
||||
<FormattedMessage
|
||||
defaultMessage="You can combine data views from any Kibana app into one dashboard and see everything in one place."
|
||||
id="dashboard.listing.createNewDashboard.combineDataViewFromKibanaAppDescription"
|
||||
values={Object {}}
|
||||
/>
|
||||
</p>
|
||||
<p>
|
||||
<FormattedMessage
|
||||
defaultMessage="New to Kibana? {sampleDataInstallLink} to take a test drive."
|
||||
id="dashboard.listing.createNewDashboard.newToKibanaDescription"
|
||||
values={
|
||||
Object {
|
||||
"sampleDataInstallLink": <EuiLink
|
||||
onClick={[Function]}
|
||||
>
|
||||
<FormattedMessage
|
||||
defaultMessage="Install some sample data"
|
||||
id="dashboard.listing.createNewDashboard.sampleDataInstallLinkText"
|
||||
values={Object {}}
|
||||
/>
|
||||
</EuiLink>,
|
||||
}
|
||||
}
|
||||
/>
|
||||
</p>
|
||||
</React.Fragment>
|
||||
}
|
||||
iconType="dashboardApp"
|
||||
title={
|
||||
<h1
|
||||
id="dashboardListingHeading"
|
||||
>
|
||||
<FormattedMessage
|
||||
defaultMessage="Create your first dashboard"
|
||||
id="dashboard.listing.createNewDashboard.title"
|
||||
values={Object {}}
|
||||
/>
|
||||
</h1>
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
}
|
||||
rowHeader="title"
|
||||
searchFilters={Array []}
|
||||
tableCaption="Dashboards"
|
||||
|
@ -372,24 +332,7 @@ exports[`after fetch initialFilter 1`] = `
|
|||
"remove": [MockFunction],
|
||||
}
|
||||
}
|
||||
>
|
||||
<EuiPage
|
||||
className="itemListing__page"
|
||||
data-test-subj="dashboardLandingPage"
|
||||
restrictWidth={true}
|
||||
>
|
||||
<div
|
||||
className="euiPage euiPage--paddingMedium euiPage--grow euiPage--restrictWidth-default itemListing__page"
|
||||
data-test-subj="dashboardLandingPage"
|
||||
>
|
||||
<EuiPageBody>
|
||||
<main
|
||||
className="euiPageBody euiPageBody--borderRadiusNone"
|
||||
/>
|
||||
</EuiPageBody>
|
||||
</div>
|
||||
</EuiPage>
|
||||
</TableListView>
|
||||
/>
|
||||
</DashboardListing>
|
||||
`;
|
||||
|
||||
|
@ -417,6 +360,66 @@ exports[`after fetch renders all table rows 1`] = `
|
|||
createItem={[Function]}
|
||||
deleteItems={[Function]}
|
||||
editItem={[Function]}
|
||||
emptyPrompt={
|
||||
<EuiEmptyPrompt
|
||||
actions={
|
||||
<EuiButton
|
||||
data-test-subj="createDashboardPromptButton"
|
||||
fill={true}
|
||||
iconType="plusInCircle"
|
||||
onClick={[Function]}
|
||||
>
|
||||
<FormattedMessage
|
||||
defaultMessage="Create new dashboard"
|
||||
id="dashboard.listing.createNewDashboard.createButtonLabel"
|
||||
values={Object {}}
|
||||
/>
|
||||
</EuiButton>
|
||||
}
|
||||
body={
|
||||
<React.Fragment>
|
||||
<p>
|
||||
<FormattedMessage
|
||||
defaultMessage="You can combine data views from any Kibana app into one dashboard and see everything in one place."
|
||||
id="dashboard.listing.createNewDashboard.combineDataViewFromKibanaAppDescription"
|
||||
values={Object {}}
|
||||
/>
|
||||
</p>
|
||||
<p>
|
||||
<FormattedMessage
|
||||
defaultMessage="New to Kibana? {sampleDataInstallLink} to take a test drive."
|
||||
id="dashboard.listing.createNewDashboard.newToKibanaDescription"
|
||||
values={
|
||||
Object {
|
||||
"sampleDataInstallLink": <EuiLink
|
||||
onClick={[Function]}
|
||||
>
|
||||
<FormattedMessage
|
||||
defaultMessage="Install some sample data"
|
||||
id="dashboard.listing.createNewDashboard.sampleDataInstallLinkText"
|
||||
values={Object {}}
|
||||
/>
|
||||
</EuiLink>,
|
||||
}
|
||||
}
|
||||
/>
|
||||
</p>
|
||||
</React.Fragment>
|
||||
}
|
||||
iconType="dashboardApp"
|
||||
title={
|
||||
<h1
|
||||
id="dashboardListingHeading"
|
||||
>
|
||||
<FormattedMessage
|
||||
defaultMessage="Create your first dashboard"
|
||||
id="dashboard.listing.createNewDashboard.title"
|
||||
values={Object {}}
|
||||
/>
|
||||
</h1>
|
||||
}
|
||||
/>
|
||||
}
|
||||
entityName="dashboard"
|
||||
entityNamePlural="dashboards"
|
||||
findItems={[Function]}
|
||||
|
@ -424,68 +427,6 @@ exports[`after fetch renders all table rows 1`] = `
|
|||
initialFilter=""
|
||||
initialPageSize={20}
|
||||
listingLimit={100}
|
||||
noItemsFragment={
|
||||
<div>
|
||||
<EuiEmptyPrompt
|
||||
actions={
|
||||
<EuiButton
|
||||
data-test-subj="createDashboardPromptButton"
|
||||
fill={true}
|
||||
iconType="plusInCircle"
|
||||
onClick={[Function]}
|
||||
>
|
||||
<FormattedMessage
|
||||
defaultMessage="Create new dashboard"
|
||||
id="dashboard.listing.createNewDashboard.createButtonLabel"
|
||||
values={Object {}}
|
||||
/>
|
||||
</EuiButton>
|
||||
}
|
||||
body={
|
||||
<React.Fragment>
|
||||
<p>
|
||||
<FormattedMessage
|
||||
defaultMessage="You can combine data views from any Kibana app into one dashboard and see everything in one place."
|
||||
id="dashboard.listing.createNewDashboard.combineDataViewFromKibanaAppDescription"
|
||||
values={Object {}}
|
||||
/>
|
||||
</p>
|
||||
<p>
|
||||
<FormattedMessage
|
||||
defaultMessage="New to Kibana? {sampleDataInstallLink} to take a test drive."
|
||||
id="dashboard.listing.createNewDashboard.newToKibanaDescription"
|
||||
values={
|
||||
Object {
|
||||
"sampleDataInstallLink": <EuiLink
|
||||
onClick={[Function]}
|
||||
>
|
||||
<FormattedMessage
|
||||
defaultMessage="Install some sample data"
|
||||
id="dashboard.listing.createNewDashboard.sampleDataInstallLinkText"
|
||||
values={Object {}}
|
||||
/>
|
||||
</EuiLink>,
|
||||
}
|
||||
}
|
||||
/>
|
||||
</p>
|
||||
</React.Fragment>
|
||||
}
|
||||
iconType="dashboardApp"
|
||||
title={
|
||||
<h1
|
||||
id="dashboardListingHeading"
|
||||
>
|
||||
<FormattedMessage
|
||||
defaultMessage="Create your first dashboard"
|
||||
id="dashboard.listing.createNewDashboard.title"
|
||||
values={Object {}}
|
||||
/>
|
||||
</h1>
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
}
|
||||
rowHeader="title"
|
||||
searchFilters={Array []}
|
||||
tableCaption="Dashboards"
|
||||
|
@ -518,24 +459,7 @@ exports[`after fetch renders all table rows 1`] = `
|
|||
"remove": [MockFunction],
|
||||
}
|
||||
}
|
||||
>
|
||||
<EuiPage
|
||||
className="itemListing__page"
|
||||
data-test-subj="dashboardLandingPage"
|
||||
restrictWidth={true}
|
||||
>
|
||||
<div
|
||||
className="euiPage euiPage--paddingMedium euiPage--grow euiPage--restrictWidth-default itemListing__page"
|
||||
data-test-subj="dashboardLandingPage"
|
||||
>
|
||||
<EuiPageBody>
|
||||
<main
|
||||
className="euiPageBody euiPageBody--borderRadiusNone"
|
||||
/>
|
||||
</EuiPageBody>
|
||||
</div>
|
||||
</EuiPage>
|
||||
</TableListView>
|
||||
/>
|
||||
</DashboardListing>
|
||||
`;
|
||||
|
||||
|
@ -563,6 +487,66 @@ exports[`after fetch renders call to action when no dashboards exist 1`] = `
|
|||
createItem={[Function]}
|
||||
deleteItems={[Function]}
|
||||
editItem={[Function]}
|
||||
emptyPrompt={
|
||||
<EuiEmptyPrompt
|
||||
actions={
|
||||
<EuiButton
|
||||
data-test-subj="createDashboardPromptButton"
|
||||
fill={true}
|
||||
iconType="plusInCircle"
|
||||
onClick={[Function]}
|
||||
>
|
||||
<FormattedMessage
|
||||
defaultMessage="Create new dashboard"
|
||||
id="dashboard.listing.createNewDashboard.createButtonLabel"
|
||||
values={Object {}}
|
||||
/>
|
||||
</EuiButton>
|
||||
}
|
||||
body={
|
||||
<React.Fragment>
|
||||
<p>
|
||||
<FormattedMessage
|
||||
defaultMessage="You can combine data views from any Kibana app into one dashboard and see everything in one place."
|
||||
id="dashboard.listing.createNewDashboard.combineDataViewFromKibanaAppDescription"
|
||||
values={Object {}}
|
||||
/>
|
||||
</p>
|
||||
<p>
|
||||
<FormattedMessage
|
||||
defaultMessage="New to Kibana? {sampleDataInstallLink} to take a test drive."
|
||||
id="dashboard.listing.createNewDashboard.newToKibanaDescription"
|
||||
values={
|
||||
Object {
|
||||
"sampleDataInstallLink": <EuiLink
|
||||
onClick={[Function]}
|
||||
>
|
||||
<FormattedMessage
|
||||
defaultMessage="Install some sample data"
|
||||
id="dashboard.listing.createNewDashboard.sampleDataInstallLinkText"
|
||||
values={Object {}}
|
||||
/>
|
||||
</EuiLink>,
|
||||
}
|
||||
}
|
||||
/>
|
||||
</p>
|
||||
</React.Fragment>
|
||||
}
|
||||
iconType="dashboardApp"
|
||||
title={
|
||||
<h1
|
||||
id="dashboardListingHeading"
|
||||
>
|
||||
<FormattedMessage
|
||||
defaultMessage="Create your first dashboard"
|
||||
id="dashboard.listing.createNewDashboard.title"
|
||||
values={Object {}}
|
||||
/>
|
||||
</h1>
|
||||
}
|
||||
/>
|
||||
}
|
||||
entityName="dashboard"
|
||||
entityNamePlural="dashboards"
|
||||
findItems={[Function]}
|
||||
|
@ -570,68 +554,6 @@ exports[`after fetch renders call to action when no dashboards exist 1`] = `
|
|||
initialFilter=""
|
||||
initialPageSize={20}
|
||||
listingLimit={100}
|
||||
noItemsFragment={
|
||||
<div>
|
||||
<EuiEmptyPrompt
|
||||
actions={
|
||||
<EuiButton
|
||||
data-test-subj="createDashboardPromptButton"
|
||||
fill={true}
|
||||
iconType="plusInCircle"
|
||||
onClick={[Function]}
|
||||
>
|
||||
<FormattedMessage
|
||||
defaultMessage="Create new dashboard"
|
||||
id="dashboard.listing.createNewDashboard.createButtonLabel"
|
||||
values={Object {}}
|
||||
/>
|
||||
</EuiButton>
|
||||
}
|
||||
body={
|
||||
<React.Fragment>
|
||||
<p>
|
||||
<FormattedMessage
|
||||
defaultMessage="You can combine data views from any Kibana app into one dashboard and see everything in one place."
|
||||
id="dashboard.listing.createNewDashboard.combineDataViewFromKibanaAppDescription"
|
||||
values={Object {}}
|
||||
/>
|
||||
</p>
|
||||
<p>
|
||||
<FormattedMessage
|
||||
defaultMessage="New to Kibana? {sampleDataInstallLink} to take a test drive."
|
||||
id="dashboard.listing.createNewDashboard.newToKibanaDescription"
|
||||
values={
|
||||
Object {
|
||||
"sampleDataInstallLink": <EuiLink
|
||||
onClick={[Function]}
|
||||
>
|
||||
<FormattedMessage
|
||||
defaultMessage="Install some sample data"
|
||||
id="dashboard.listing.createNewDashboard.sampleDataInstallLinkText"
|
||||
values={Object {}}
|
||||
/>
|
||||
</EuiLink>,
|
||||
}
|
||||
}
|
||||
/>
|
||||
</p>
|
||||
</React.Fragment>
|
||||
}
|
||||
iconType="dashboardApp"
|
||||
title={
|
||||
<h1
|
||||
id="dashboardListingHeading"
|
||||
>
|
||||
<FormattedMessage
|
||||
defaultMessage="Create your first dashboard"
|
||||
id="dashboard.listing.createNewDashboard.title"
|
||||
values={Object {}}
|
||||
/>
|
||||
</h1>
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
}
|
||||
rowHeader="title"
|
||||
searchFilters={Array []}
|
||||
tableCaption="Dashboards"
|
||||
|
@ -664,24 +586,7 @@ exports[`after fetch renders call to action when no dashboards exist 1`] = `
|
|||
"remove": [MockFunction],
|
||||
}
|
||||
}
|
||||
>
|
||||
<EuiPage
|
||||
className="itemListing__page"
|
||||
data-test-subj="dashboardLandingPage"
|
||||
restrictWidth={true}
|
||||
>
|
||||
<div
|
||||
className="euiPage euiPage--paddingMedium euiPage--grow euiPage--restrictWidth-default itemListing__page"
|
||||
data-test-subj="dashboardLandingPage"
|
||||
>
|
||||
<EuiPageBody>
|
||||
<main
|
||||
className="euiPageBody euiPageBody--borderRadiusNone"
|
||||
/>
|
||||
</EuiPageBody>
|
||||
</div>
|
||||
</EuiPage>
|
||||
</TableListView>
|
||||
/>
|
||||
</DashboardListing>
|
||||
`;
|
||||
|
||||
|
@ -709,6 +614,66 @@ exports[`after fetch renders warning when listingLimit is exceeded 1`] = `
|
|||
createItem={[Function]}
|
||||
deleteItems={[Function]}
|
||||
editItem={[Function]}
|
||||
emptyPrompt={
|
||||
<EuiEmptyPrompt
|
||||
actions={
|
||||
<EuiButton
|
||||
data-test-subj="createDashboardPromptButton"
|
||||
fill={true}
|
||||
iconType="plusInCircle"
|
||||
onClick={[Function]}
|
||||
>
|
||||
<FormattedMessage
|
||||
defaultMessage="Create new dashboard"
|
||||
id="dashboard.listing.createNewDashboard.createButtonLabel"
|
||||
values={Object {}}
|
||||
/>
|
||||
</EuiButton>
|
||||
}
|
||||
body={
|
||||
<React.Fragment>
|
||||
<p>
|
||||
<FormattedMessage
|
||||
defaultMessage="You can combine data views from any Kibana app into one dashboard and see everything in one place."
|
||||
id="dashboard.listing.createNewDashboard.combineDataViewFromKibanaAppDescription"
|
||||
values={Object {}}
|
||||
/>
|
||||
</p>
|
||||
<p>
|
||||
<FormattedMessage
|
||||
defaultMessage="New to Kibana? {sampleDataInstallLink} to take a test drive."
|
||||
id="dashboard.listing.createNewDashboard.newToKibanaDescription"
|
||||
values={
|
||||
Object {
|
||||
"sampleDataInstallLink": <EuiLink
|
||||
onClick={[Function]}
|
||||
>
|
||||
<FormattedMessage
|
||||
defaultMessage="Install some sample data"
|
||||
id="dashboard.listing.createNewDashboard.sampleDataInstallLinkText"
|
||||
values={Object {}}
|
||||
/>
|
||||
</EuiLink>,
|
||||
}
|
||||
}
|
||||
/>
|
||||
</p>
|
||||
</React.Fragment>
|
||||
}
|
||||
iconType="dashboardApp"
|
||||
title={
|
||||
<h1
|
||||
id="dashboardListingHeading"
|
||||
>
|
||||
<FormattedMessage
|
||||
defaultMessage="Create your first dashboard"
|
||||
id="dashboard.listing.createNewDashboard.title"
|
||||
values={Object {}}
|
||||
/>
|
||||
</h1>
|
||||
}
|
||||
/>
|
||||
}
|
||||
entityName="dashboard"
|
||||
entityNamePlural="dashboards"
|
||||
findItems={[Function]}
|
||||
|
@ -716,68 +681,6 @@ exports[`after fetch renders warning when listingLimit is exceeded 1`] = `
|
|||
initialFilter=""
|
||||
initialPageSize={20}
|
||||
listingLimit={1}
|
||||
noItemsFragment={
|
||||
<div>
|
||||
<EuiEmptyPrompt
|
||||
actions={
|
||||
<EuiButton
|
||||
data-test-subj="createDashboardPromptButton"
|
||||
fill={true}
|
||||
iconType="plusInCircle"
|
||||
onClick={[Function]}
|
||||
>
|
||||
<FormattedMessage
|
||||
defaultMessage="Create new dashboard"
|
||||
id="dashboard.listing.createNewDashboard.createButtonLabel"
|
||||
values={Object {}}
|
||||
/>
|
||||
</EuiButton>
|
||||
}
|
||||
body={
|
||||
<React.Fragment>
|
||||
<p>
|
||||
<FormattedMessage
|
||||
defaultMessage="You can combine data views from any Kibana app into one dashboard and see everything in one place."
|
||||
id="dashboard.listing.createNewDashboard.combineDataViewFromKibanaAppDescription"
|
||||
values={Object {}}
|
||||
/>
|
||||
</p>
|
||||
<p>
|
||||
<FormattedMessage
|
||||
defaultMessage="New to Kibana? {sampleDataInstallLink} to take a test drive."
|
||||
id="dashboard.listing.createNewDashboard.newToKibanaDescription"
|
||||
values={
|
||||
Object {
|
||||
"sampleDataInstallLink": <EuiLink
|
||||
onClick={[Function]}
|
||||
>
|
||||
<FormattedMessage
|
||||
defaultMessage="Install some sample data"
|
||||
id="dashboard.listing.createNewDashboard.sampleDataInstallLinkText"
|
||||
values={Object {}}
|
||||
/>
|
||||
</EuiLink>,
|
||||
}
|
||||
}
|
||||
/>
|
||||
</p>
|
||||
</React.Fragment>
|
||||
}
|
||||
iconType="dashboardApp"
|
||||
title={
|
||||
<h1
|
||||
id="dashboardListingHeading"
|
||||
>
|
||||
<FormattedMessage
|
||||
defaultMessage="Create your first dashboard"
|
||||
id="dashboard.listing.createNewDashboard.title"
|
||||
values={Object {}}
|
||||
/>
|
||||
</h1>
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
}
|
||||
rowHeader="title"
|
||||
searchFilters={Array []}
|
||||
tableCaption="Dashboards"
|
||||
|
@ -810,23 +713,6 @@ exports[`after fetch renders warning when listingLimit is exceeded 1`] = `
|
|||
"remove": [MockFunction],
|
||||
}
|
||||
}
|
||||
>
|
||||
<EuiPage
|
||||
className="itemListing__page"
|
||||
data-test-subj="dashboardLandingPage"
|
||||
restrictWidth={true}
|
||||
>
|
||||
<div
|
||||
className="euiPage euiPage--paddingMedium euiPage--grow euiPage--restrictWidth-default itemListing__page"
|
||||
data-test-subj="dashboardLandingPage"
|
||||
>
|
||||
<EuiPageBody>
|
||||
<main
|
||||
className="euiPageBody euiPageBody--borderRadiusNone"
|
||||
/>
|
||||
</EuiPageBody>
|
||||
</div>
|
||||
</EuiPage>
|
||||
</TableListView>
|
||||
/>
|
||||
</DashboardListing>
|
||||
`;
|
||||
|
|
|
@ -113,7 +113,7 @@ export const DashboardListing = ({
|
|||
}
|
||||
}, [dashboardPanelStorage, redirectTo, core.overlays]);
|
||||
|
||||
const noItemsFragment = useMemo(
|
||||
const emptyPrompt = useMemo(
|
||||
() => getNoItemsMessage(hideWriteControls, core.application, createItem),
|
||||
[createItem, core.application, hideWriteControls]
|
||||
);
|
||||
|
@ -181,7 +181,7 @@ export const DashboardListing = ({
|
|||
tableCaption={getTableCaption()}
|
||||
entityName={getEntityName()}
|
||||
{...{
|
||||
noItemsFragment,
|
||||
emptyPrompt,
|
||||
searchFilters,
|
||||
listingLimit,
|
||||
tableColumns,
|
||||
|
@ -241,80 +241,76 @@ const getNoItemsMessage = (
|
|||
) => {
|
||||
if (hideWriteControls) {
|
||||
return (
|
||||
<div>
|
||||
<EuiEmptyPrompt
|
||||
iconType="dashboardApp"
|
||||
title={
|
||||
<h1 id="dashboardListingHeading">
|
||||
<FormattedMessage
|
||||
id="dashboard.listing.noItemsMessage"
|
||||
defaultMessage="Looks like you don't have any dashboards."
|
||||
/>
|
||||
</h1>
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
<EuiEmptyPrompt
|
||||
iconType="dashboardApp"
|
||||
title={
|
||||
<h1 id="dashboardListingHeading">
|
||||
<FormattedMessage
|
||||
id="dashboard.listing.createNewDashboard.title"
|
||||
defaultMessage="Create your first dashboard"
|
||||
id="dashboard.listing.noItemsMessage"
|
||||
defaultMessage="Looks like you don't have any dashboards."
|
||||
/>
|
||||
</h1>
|
||||
}
|
||||
body={
|
||||
<Fragment>
|
||||
<p>
|
||||
<FormattedMessage
|
||||
id="dashboard.listing.createNewDashboard.combineDataViewFromKibanaAppDescription"
|
||||
defaultMessage="You can combine data views from any Kibana app into one dashboard and see everything in one place."
|
||||
/>
|
||||
</p>
|
||||
<p>
|
||||
<FormattedMessage
|
||||
id="dashboard.listing.createNewDashboard.newToKibanaDescription"
|
||||
defaultMessage="New to Kibana? {sampleDataInstallLink} to take a test drive."
|
||||
values={{
|
||||
sampleDataInstallLink: (
|
||||
<EuiLink
|
||||
onClick={() =>
|
||||
application.navigateToApp('home', {
|
||||
path: '#/tutorial_directory/sampleData',
|
||||
})
|
||||
}
|
||||
>
|
||||
<FormattedMessage
|
||||
id="dashboard.listing.createNewDashboard.sampleDataInstallLinkText"
|
||||
defaultMessage="Install some sample data"
|
||||
/>
|
||||
</EuiLink>
|
||||
),
|
||||
}}
|
||||
/>
|
||||
</p>
|
||||
</Fragment>
|
||||
}
|
||||
actions={
|
||||
<EuiButton
|
||||
onClick={createItem}
|
||||
fill
|
||||
iconType="plusInCircle"
|
||||
data-test-subj="createDashboardPromptButton"
|
||||
>
|
||||
<FormattedMessage
|
||||
id="dashboard.listing.createNewDashboard.createButtonLabel"
|
||||
defaultMessage="Create new dashboard"
|
||||
/>
|
||||
</EuiButton>
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<EuiEmptyPrompt
|
||||
iconType="dashboardApp"
|
||||
title={
|
||||
<h1 id="dashboardListingHeading">
|
||||
<FormattedMessage
|
||||
id="dashboard.listing.createNewDashboard.title"
|
||||
defaultMessage="Create your first dashboard"
|
||||
/>
|
||||
</h1>
|
||||
}
|
||||
body={
|
||||
<Fragment>
|
||||
<p>
|
||||
<FormattedMessage
|
||||
id="dashboard.listing.createNewDashboard.combineDataViewFromKibanaAppDescription"
|
||||
defaultMessage="You can combine data views from any Kibana app into one dashboard and see everything in one place."
|
||||
/>
|
||||
</p>
|
||||
<p>
|
||||
<FormattedMessage
|
||||
id="dashboard.listing.createNewDashboard.newToKibanaDescription"
|
||||
defaultMessage="New to Kibana? {sampleDataInstallLink} to take a test drive."
|
||||
values={{
|
||||
sampleDataInstallLink: (
|
||||
<EuiLink
|
||||
onClick={() =>
|
||||
application.navigateToApp('home', {
|
||||
path: '#/tutorial_directory/sampleData',
|
||||
})
|
||||
}
|
||||
>
|
||||
<FormattedMessage
|
||||
id="dashboard.listing.createNewDashboard.sampleDataInstallLinkText"
|
||||
defaultMessage="Install some sample data"
|
||||
/>
|
||||
</EuiLink>
|
||||
),
|
||||
}}
|
||||
/>
|
||||
</p>
|
||||
</Fragment>
|
||||
}
|
||||
actions={
|
||||
<EuiButton
|
||||
onClick={createItem}
|
||||
fill
|
||||
iconType="plusInCircle"
|
||||
data-test-subj="createDashboardPromptButton"
|
||||
>
|
||||
<FormattedMessage
|
||||
id="dashboard.listing.createNewDashboard.createButtonLabel"
|
||||
defaultMessage="Create new dashboard"
|
||||
/>
|
||||
</EuiButton>
|
||||
}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -19,6 +19,7 @@ export * from './table_list_view';
|
|||
export * from './toolbar_button';
|
||||
export * from './split_panel';
|
||||
export * from './react_router_navigate';
|
||||
export * from './page_template';
|
||||
export { ValidatedDualRange, Value } from './validated_range';
|
||||
export * from './notifications';
|
||||
export { Markdown, MarkdownSimple } from './markdown';
|
||||
|
|
78
src/plugins/kibana_react/public/page_template/__snapshots__/page_template.test.tsx.snap
generated
Normal file
78
src/plugins/kibana_react/public/page_template/__snapshots__/page_template.test.tsx.snap
generated
Normal file
|
@ -0,0 +1,78 @@
|
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`KibanaPageTemplate render basic template 1`] = `
|
||||
<EuiPageTemplate
|
||||
pageHeader={
|
||||
Object {
|
||||
"description": "test",
|
||||
"iconType": "test",
|
||||
"rightSideItems": Array [
|
||||
"test",
|
||||
],
|
||||
"title": "test",
|
||||
}
|
||||
}
|
||||
restrictWidth={true}
|
||||
/>
|
||||
`;
|
||||
|
||||
exports[`KibanaPageTemplate render custom empty prompt only 1`] = `
|
||||
<EuiPageTemplate
|
||||
restrictWidth={true}
|
||||
template="centeredBody"
|
||||
>
|
||||
<EuiEmptyPrompt
|
||||
title={
|
||||
<h1>
|
||||
custom test
|
||||
</h1>
|
||||
}
|
||||
/>
|
||||
</EuiPageTemplate>
|
||||
`;
|
||||
|
||||
exports[`KibanaPageTemplate render custom empty prompt with page header 1`] = `
|
||||
<EuiPageTemplate
|
||||
pageHeader={
|
||||
Object {
|
||||
"description": "test",
|
||||
"iconType": "test",
|
||||
"rightSideItems": Array [
|
||||
"test",
|
||||
],
|
||||
"title": "test",
|
||||
}
|
||||
}
|
||||
restrictWidth={true}
|
||||
template="centeredContent"
|
||||
>
|
||||
<EuiEmptyPrompt
|
||||
title={
|
||||
<h1>
|
||||
custom test
|
||||
</h1>
|
||||
}
|
||||
/>
|
||||
</EuiPageTemplate>
|
||||
`;
|
||||
|
||||
exports[`KibanaPageTemplate render default empty prompt 1`] = `
|
||||
<EuiPageTemplate
|
||||
restrictWidth={true}
|
||||
template="centeredBody"
|
||||
>
|
||||
<EuiEmptyPrompt
|
||||
actions={
|
||||
Array [
|
||||
"test",
|
||||
]
|
||||
}
|
||||
body={
|
||||
<p>
|
||||
test
|
||||
</p>
|
||||
}
|
||||
iconType="test"
|
||||
/>
|
||||
</EuiPageTemplate>
|
||||
`;
|
9
src/plugins/kibana_react/public/page_template/index.ts
Normal file
9
src/plugins/kibana_react/public/page_template/index.ts
Normal file
|
@ -0,0 +1,9 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
export { KibanaPageTemplate, KibanaPageTemplateProps } from './page_template';
|
|
@ -0,0 +1,69 @@
|
|||
/*
|
||||
* 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 { shallow } from 'enzyme';
|
||||
import { KibanaPageTemplate } from './page_template';
|
||||
import { EuiEmptyPrompt } from '@elastic/eui';
|
||||
|
||||
describe('KibanaPageTemplate', () => {
|
||||
test('render default empty prompt', () => {
|
||||
const component = shallow(
|
||||
<KibanaPageTemplate
|
||||
isEmptyState={true}
|
||||
pageHeader={{
|
||||
iconType: 'test',
|
||||
title: 'test',
|
||||
description: 'test',
|
||||
rightSideItems: ['test'],
|
||||
}}
|
||||
/>
|
||||
);
|
||||
expect(component).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('render custom empty prompt only', () => {
|
||||
const component = shallow(
|
||||
<KibanaPageTemplate isEmptyState={true}>
|
||||
<EuiEmptyPrompt title={<h1>custom test</h1>} />
|
||||
</KibanaPageTemplate>
|
||||
);
|
||||
expect(component).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('render custom empty prompt with page header', () => {
|
||||
const component = shallow(
|
||||
<KibanaPageTemplate
|
||||
isEmptyState={true}
|
||||
pageHeader={{
|
||||
iconType: 'test',
|
||||
title: 'test',
|
||||
description: 'test',
|
||||
rightSideItems: ['test'],
|
||||
}}
|
||||
>
|
||||
<EuiEmptyPrompt title={<h1>custom test</h1>} />
|
||||
</KibanaPageTemplate>
|
||||
);
|
||||
expect(component).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('render basic template', () => {
|
||||
const component = shallow(
|
||||
<KibanaPageTemplate
|
||||
pageHeader={{
|
||||
iconType: 'test',
|
||||
title: 'test',
|
||||
description: 'test',
|
||||
rightSideItems: ['test'],
|
||||
}}
|
||||
/>
|
||||
);
|
||||
expect(component).toMatchSnapshot();
|
||||
});
|
||||
});
|
|
@ -0,0 +1,73 @@
|
|||
/*
|
||||
* 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 { EuiEmptyPrompt, EuiPageTemplate, EuiPageTemplateProps } from '@elastic/eui';
|
||||
import React, { FunctionComponent } from 'react';
|
||||
|
||||
export type KibanaPageTemplateProps = EuiPageTemplateProps & {
|
||||
/**
|
||||
* Changes the template type depending on other props provided.
|
||||
* With `pageHeader` only: Uses `centeredBody` and fills an EuiEmptyPrompt with `pageHeader` info.
|
||||
* With `children` only: Uses `centeredBody`
|
||||
* With `pageHeader` and `children`: Uses `centeredContent`
|
||||
*/
|
||||
isEmptyState?: boolean;
|
||||
};
|
||||
|
||||
export const KibanaPageTemplate: FunctionComponent<KibanaPageTemplateProps> = ({
|
||||
template,
|
||||
pageHeader,
|
||||
children,
|
||||
isEmptyState,
|
||||
restrictWidth = true,
|
||||
bottomBar,
|
||||
bottomBarProps,
|
||||
...rest
|
||||
}) => {
|
||||
// Needed for differentiating between union types
|
||||
let localBottomBarProps = {};
|
||||
if (template === 'default') {
|
||||
localBottomBarProps = {
|
||||
bottomBar,
|
||||
bottomBarProps,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* An easy way to create the right content for empty pages
|
||||
*/
|
||||
if (isEmptyState && pageHeader && !children) {
|
||||
template = template ?? 'centeredBody';
|
||||
const { iconType, pageTitle, description, rightSideItems } = pageHeader;
|
||||
pageHeader = undefined;
|
||||
children = (
|
||||
<EuiEmptyPrompt
|
||||
iconType={iconType}
|
||||
title={pageTitle ? <h1>{pageTitle}</h1> : undefined}
|
||||
body={description ? <p>{description}</p> : undefined}
|
||||
actions={rightSideItems}
|
||||
/>
|
||||
);
|
||||
} else if (isEmptyState && pageHeader && children) {
|
||||
template = template ?? 'centeredContent';
|
||||
} else if (isEmptyState && !pageHeader) {
|
||||
template = template ?? 'centeredBody';
|
||||
}
|
||||
|
||||
return (
|
||||
<EuiPageTemplate
|
||||
template={template}
|
||||
pageHeader={pageHeader}
|
||||
restrictWidth={restrictWidth}
|
||||
{...localBottomBarProps}
|
||||
{...rest}
|
||||
>
|
||||
{children}
|
||||
</EuiPageTemplate>
|
||||
);
|
||||
};
|
117
src/plugins/kibana_react/public/table_list_view/__snapshots__/table_list_view.test.tsx.snap
generated
Normal file
117
src/plugins/kibana_react/public/table_list_view/__snapshots__/table_list_view.test.tsx.snap
generated
Normal file
|
@ -0,0 +1,117 @@
|
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`TableListView render custom empty prompt 1`] = `
|
||||
<KibanaPageTemplate
|
||||
data-test-subj="testLandingPage"
|
||||
isEmptyState={true}
|
||||
pageBodyProps={
|
||||
Object {
|
||||
"aria-labelledby": undefined,
|
||||
}
|
||||
}
|
||||
>
|
||||
<EuiEmptyPrompt />
|
||||
</KibanaPageTemplate>
|
||||
`;
|
||||
|
||||
exports[`TableListView render default empty prompt 1`] = `
|
||||
<KibanaPageTemplate
|
||||
data-test-subj="testLandingPage"
|
||||
isEmptyState={true}
|
||||
pageBodyProps={
|
||||
Object {
|
||||
"aria-labelledby": undefined,
|
||||
}
|
||||
}
|
||||
>
|
||||
<EuiEmptyPrompt
|
||||
title={
|
||||
<h1>
|
||||
<FormattedMessage
|
||||
defaultMessage="No {entityNamePlural} available."
|
||||
id="kibana-react.tableListView.listing.noAvailableItemsMessage"
|
||||
values={
|
||||
Object {
|
||||
"entityNamePlural": "tests",
|
||||
}
|
||||
}
|
||||
/>
|
||||
</h1>
|
||||
}
|
||||
/>
|
||||
</KibanaPageTemplate>
|
||||
`;
|
||||
|
||||
exports[`TableListView render list view 1`] = `
|
||||
<KibanaPageTemplate
|
||||
data-test-subj="testLandingPage"
|
||||
pageBodyProps={
|
||||
Object {
|
||||
"aria-labelledby": undefined,
|
||||
}
|
||||
}
|
||||
pageHeader={
|
||||
Object {
|
||||
"data-test-subj": "top-nav",
|
||||
"pageTitle": <span>
|
||||
test title
|
||||
</span>,
|
||||
"rightSideItems": Array [
|
||||
undefined,
|
||||
],
|
||||
}
|
||||
}
|
||||
>
|
||||
<EuiInMemoryTable
|
||||
columns={Array []}
|
||||
data-test-subj="itemsInMemTable"
|
||||
itemId="id"
|
||||
items={
|
||||
Array [
|
||||
Object {},
|
||||
]
|
||||
}
|
||||
loading={false}
|
||||
message={
|
||||
<FormattedMessage
|
||||
defaultMessage="No {entityNamePlural} matched your search."
|
||||
id="kibana-react.tableListView.listing.noMatchedItemsMessage"
|
||||
values={
|
||||
Object {
|
||||
"entityNamePlural": "tests",
|
||||
}
|
||||
}
|
||||
/>
|
||||
}
|
||||
pagination={
|
||||
Object {
|
||||
"initialPageIndex": 0,
|
||||
"initialPageSize": 5,
|
||||
"pageSizeOptions": Array [
|
||||
10,
|
||||
20,
|
||||
5,
|
||||
50,
|
||||
],
|
||||
}
|
||||
}
|
||||
responsive={true}
|
||||
rowHeader="name"
|
||||
search={
|
||||
Object {
|
||||
"box": Object {
|
||||
"data-test-subj": "tableListSearchBox",
|
||||
"incremental": true,
|
||||
},
|
||||
"defaultQuery": "",
|
||||
"filters": Array [],
|
||||
"onChange": [Function],
|
||||
"toolsLeft": undefined,
|
||||
}
|
||||
}
|
||||
sorting={true}
|
||||
tableCaption="test caption"
|
||||
tableLayout="fixed"
|
||||
/>
|
||||
</KibanaPageTemplate>
|
||||
`;
|
|
@ -0,0 +1,68 @@
|
|||
/*
|
||||
* 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 { EuiEmptyPrompt } from '@elastic/eui';
|
||||
import { shallowWithIntl } from '@kbn/test/jest';
|
||||
import { ToastsStart } from 'kibana/public';
|
||||
import React from 'react';
|
||||
import { TableListView } from './table_list_view';
|
||||
|
||||
const requiredProps = {
|
||||
entityName: 'test',
|
||||
entityNamePlural: 'tests',
|
||||
listingLimit: 5,
|
||||
initialFilter: '',
|
||||
initialPageSize: 5,
|
||||
tableColumns: [],
|
||||
tableListTitle: 'test title',
|
||||
rowHeader: 'name',
|
||||
tableCaption: 'test caption',
|
||||
toastNotifications: {} as ToastsStart,
|
||||
findItems: jest.fn(() => Promise.resolve({ total: 0, hits: [] })),
|
||||
};
|
||||
|
||||
describe('TableListView', () => {
|
||||
test('render default empty prompt', async () => {
|
||||
const component = shallowWithIntl(<TableListView {...requiredProps} />);
|
||||
|
||||
// Using setState to check the final render while sidestepping the debounced promise management
|
||||
component.setState({
|
||||
hasInitialFetchReturned: true,
|
||||
isFetchingItems: false,
|
||||
});
|
||||
|
||||
expect(component).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('render custom empty prompt', () => {
|
||||
const component = shallowWithIntl(
|
||||
<TableListView {...requiredProps} emptyPrompt={<EuiEmptyPrompt />} />
|
||||
);
|
||||
|
||||
// Using setState to check the final render while sidestepping the debounced promise management
|
||||
component.setState({
|
||||
hasInitialFetchReturned: true,
|
||||
isFetchingItems: false,
|
||||
});
|
||||
|
||||
expect(component).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('render list view', () => {
|
||||
const component = shallowWithIntl(<TableListView {...requiredProps} />);
|
||||
|
||||
// Using setState to check the final render while sidestepping the debounced promise management
|
||||
component.setState({
|
||||
hasInitialFetchReturned: true,
|
||||
isFetchingItems: false,
|
||||
items: [{}],
|
||||
});
|
||||
|
||||
expect(component).toMatchSnapshot();
|
||||
});
|
||||
});
|
|
@ -6,29 +6,24 @@
|
|||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { FormattedMessage } from '@kbn/i18n/react';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { debounce, keyBy, sortBy, uniq } from 'lodash';
|
||||
import {
|
||||
EuiTitle,
|
||||
EuiInMemoryTable,
|
||||
EuiPage,
|
||||
EuiPageBody,
|
||||
EuiPageContent,
|
||||
EuiLink,
|
||||
EuiFlexGroup,
|
||||
EuiFlexItem,
|
||||
EuiButton,
|
||||
EuiSpacer,
|
||||
EuiConfirmModal,
|
||||
EuiCallOut,
|
||||
EuiBasicTableColumn,
|
||||
EuiButton,
|
||||
EuiCallOut,
|
||||
EuiConfirmModal,
|
||||
EuiEmptyPrompt,
|
||||
EuiInMemoryTable,
|
||||
EuiLink,
|
||||
EuiSpacer,
|
||||
EuiTableActionsColumnType,
|
||||
SearchFilterConfig,
|
||||
} from '@elastic/eui';
|
||||
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { FormattedMessage } from '@kbn/i18n/react';
|
||||
import { HttpFetchError, ToastsStart } from 'kibana/public';
|
||||
import { debounce, keyBy, sortBy, uniq } from 'lodash';
|
||||
import React from 'react';
|
||||
import { KibanaPageTemplate } from '../page_template';
|
||||
import { toMountPoint } from '../util';
|
||||
|
||||
interface Item {
|
||||
|
@ -45,7 +40,10 @@ export interface TableListViewProps {
|
|||
listingLimit: number;
|
||||
initialFilter: string;
|
||||
initialPageSize: number;
|
||||
noItemsFragment?: JSX.Element;
|
||||
/**
|
||||
* Should be an EuiEmptyPrompt (but TS doesn't support this typing)
|
||||
*/
|
||||
emptyPrompt?: JSX.Element;
|
||||
tableColumns: Array<EuiBasicTableColumn<any>>;
|
||||
tableListTitle: string;
|
||||
toastNotifications: ToastsStart;
|
||||
|
@ -61,7 +59,7 @@ export interface TableListViewProps {
|
|||
/**
|
||||
* Describes the content of the table. If not specified, the caption will be "This table contains {itemCount} rows."
|
||||
*/
|
||||
tableCaption?: string;
|
||||
tableCaption: string;
|
||||
searchFilters?: SearchFilterConfig[];
|
||||
}
|
||||
|
||||
|
@ -347,6 +345,28 @@ class TableListView extends React.Component<TableListViewProps, TableListViewSta
|
|||
}
|
||||
}
|
||||
|
||||
renderNoItemsMessage() {
|
||||
if (this.props.emptyPrompt) {
|
||||
return this.props.emptyPrompt;
|
||||
} else {
|
||||
return (
|
||||
<EuiEmptyPrompt
|
||||
title={
|
||||
<h1>
|
||||
{
|
||||
<FormattedMessage
|
||||
id="kibana-react.tableListView.listing.noAvailableItemsMessage"
|
||||
defaultMessage="No {entityNamePlural} available."
|
||||
values={{ entityNamePlural: this.props.entityNamePlural }}
|
||||
/>
|
||||
}
|
||||
</h1>
|
||||
}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
renderToolsLeft() {
|
||||
const selection = this.state.selectedIds;
|
||||
|
||||
|
@ -458,83 +478,66 @@ class TableListView extends React.Component<TableListViewProps, TableListViewSta
|
|||
);
|
||||
}
|
||||
|
||||
renderListingOrEmptyState() {
|
||||
if (this.props.noItemsFragment && !this.state.fetchError && this.hasNoItems()) {
|
||||
return this.props.noItemsFragment;
|
||||
}
|
||||
return this.renderListing();
|
||||
}
|
||||
|
||||
renderListing() {
|
||||
let createButton;
|
||||
renderCreateButton() {
|
||||
if (this.props.createItem) {
|
||||
createButton = (
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiButton
|
||||
onClick={this.props.createItem}
|
||||
data-test-subj="newItemButton"
|
||||
iconType="plusInCircle"
|
||||
fill
|
||||
>
|
||||
<FormattedMessage
|
||||
id="kibana-react.tableListView.listing.createNewItemButtonLabel"
|
||||
defaultMessage="Create {entityName}"
|
||||
values={{ entityName: this.props.entityName }}
|
||||
/>
|
||||
</EuiButton>
|
||||
</EuiFlexItem>
|
||||
return (
|
||||
<EuiButton
|
||||
onClick={this.props.createItem}
|
||||
data-test-subj="newItemButton"
|
||||
iconType="plusInCircleFilled"
|
||||
fill
|
||||
>
|
||||
<FormattedMessage
|
||||
id="kibana-react.tableListView.listing.createNewItemButtonLabel"
|
||||
defaultMessage="Create {entityName}"
|
||||
values={{ entityName: this.props.entityName }}
|
||||
/>
|
||||
</EuiButton>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<div>
|
||||
{this.state.showDeleteModal && this.renderConfirmDeleteModal()}
|
||||
|
||||
<EuiFlexGroup justifyContent="spaceBetween" alignItems="flexEnd" data-test-subj="top-nav">
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiTitle size="l">
|
||||
<h1 id={this.props.headingId}>{this.props.tableListTitle}</h1>
|
||||
</EuiTitle>
|
||||
</EuiFlexItem>
|
||||
|
||||
{createButton}
|
||||
</EuiFlexGroup>
|
||||
|
||||
<EuiSpacer size="m" />
|
||||
{this.props.children}
|
||||
|
||||
{this.renderListingLimitWarning()}
|
||||
{this.renderFetchError()}
|
||||
|
||||
{this.renderTable()}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
renderPageContent() {
|
||||
if (!this.state.hasInitialFetchReturned) {
|
||||
return;
|
||||
}
|
||||
|
||||
return (
|
||||
<EuiPageContent horizontalPosition="center">
|
||||
{this.renderListingOrEmptyState()}
|
||||
</EuiPageContent>
|
||||
);
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<EuiPage
|
||||
data-test-subj={this.props.entityName + 'LandingPage'}
|
||||
className="itemListing__page"
|
||||
restrictWidth
|
||||
>
|
||||
<EuiPageBody
|
||||
aria-labelledby={this.state.hasInitialFetchReturned ? this.props.headingId : undefined}
|
||||
const pageDTS = `${this.props.entityName}LandingPage`;
|
||||
|
||||
if (!this.state.hasInitialFetchReturned) {
|
||||
return <></>;
|
||||
}
|
||||
|
||||
if (!this.state.fetchError && this.hasNoItems()) {
|
||||
return (
|
||||
<KibanaPageTemplate
|
||||
data-test-subj={pageDTS}
|
||||
pageBodyProps={{
|
||||
'aria-labelledby': this.state.hasInitialFetchReturned
|
||||
? this.props.headingId
|
||||
: undefined,
|
||||
}}
|
||||
isEmptyState={true}
|
||||
>
|
||||
{this.renderPageContent()}
|
||||
</EuiPageBody>
|
||||
</EuiPage>
|
||||
{this.renderNoItemsMessage()}
|
||||
</KibanaPageTemplate>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<KibanaPageTemplate
|
||||
data-test-subj={pageDTS}
|
||||
pageHeader={{
|
||||
pageTitle: <span id={this.props.headingId}>{this.props.tableListTitle}</span>,
|
||||
rightSideItems: [this.renderCreateButton()],
|
||||
'data-test-subj': 'top-nav',
|
||||
}}
|
||||
pageBodyProps={{
|
||||
'aria-labelledby': this.state.hasInitialFetchReturned ? this.props.headingId : undefined,
|
||||
}}
|
||||
>
|
||||
{this.state.showDeleteModal && this.renderConfirmDeleteModal()}
|
||||
{this.props.children}
|
||||
{this.renderListingLimitWarning()}
|
||||
{this.renderFetchError()}
|
||||
{this.renderTable()}
|
||||
</KibanaPageTemplate>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -196,7 +196,7 @@ export const VisualizeListing = () => {
|
|||
initialPageSize={savedObjectsPublic.settings.getPerPage()}
|
||||
initialFilter={''}
|
||||
rowHeader="title"
|
||||
noItemsFragment={noItemsFragment}
|
||||
emptyPrompt={noItemsFragment}
|
||||
entityName={i18n.translate('visualize.listing.table.entityName', {
|
||||
defaultMessage: 'visualization',
|
||||
})}
|
||||
|
|
|
@ -45,7 +45,7 @@ export function Listing(props: ListingProps) {
|
|||
listingLimit={props.listingLimit}
|
||||
initialFilter={props.initialFilter}
|
||||
initialPageSize={props.initialPageSize}
|
||||
noItemsFragment={getNoItemsMessage(
|
||||
emptyPrompt={getNoItemsMessage(
|
||||
props.capabilities.save === false,
|
||||
props.createItem,
|
||||
props.coreStart.application
|
||||
|
@ -72,77 +72,73 @@ function getNoItemsMessage(
|
|||
) {
|
||||
if (hideWriteControls) {
|
||||
return (
|
||||
<div>
|
||||
<EuiEmptyPrompt
|
||||
iconType="graphApp"
|
||||
title={
|
||||
<h1 id="graphListingHeading">
|
||||
<FormattedMessage
|
||||
id="xpack.graph.listing.noItemsMessage"
|
||||
defaultMessage="Looks like you don't have any graphs."
|
||||
/>
|
||||
</h1>
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
<EuiEmptyPrompt
|
||||
iconType="graphApp"
|
||||
title={
|
||||
<h1 id="graphListingHeading">
|
||||
<FormattedMessage
|
||||
id="xpack.graph.listing.noItemsMessage"
|
||||
defaultMessage="Looks like you don't have any graphs."
|
||||
/>
|
||||
</h1>
|
||||
}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
const sampleDataUrl = `${application.getUrlForApp('home')}#/tutorial_directory/sampleData`;
|
||||
|
||||
return (
|
||||
<div>
|
||||
<EuiEmptyPrompt
|
||||
iconType="graphApp"
|
||||
title={
|
||||
<h1 id="graphListingHeading">
|
||||
<EuiEmptyPrompt
|
||||
iconType="graphApp"
|
||||
title={
|
||||
<h1 id="graphListingHeading">
|
||||
<FormattedMessage
|
||||
id="xpack.graph.listing.createNewGraph.title"
|
||||
defaultMessage="Create your first graph"
|
||||
/>
|
||||
</h1>
|
||||
}
|
||||
body={
|
||||
<Fragment>
|
||||
<p>
|
||||
<FormattedMessage
|
||||
id="xpack.graph.listing.createNewGraph.title"
|
||||
defaultMessage="Create your first graph"
|
||||
id="xpack.graph.listing.createNewGraph.combineDataViewFromKibanaAppDescription"
|
||||
defaultMessage="Discover patterns and relationships in your Elasticsearch indices."
|
||||
/>
|
||||
</h1>
|
||||
}
|
||||
body={
|
||||
<Fragment>
|
||||
<p>
|
||||
<FormattedMessage
|
||||
id="xpack.graph.listing.createNewGraph.combineDataViewFromKibanaAppDescription"
|
||||
defaultMessage="Discover patterns and relationships in your Elasticsearch indices."
|
||||
/>
|
||||
</p>
|
||||
<p>
|
||||
<FormattedMessage
|
||||
id="xpack.graph.listing.createNewGraph.newToKibanaDescription"
|
||||
defaultMessage="New to Kibana? Get started with {sampleDataInstallLink}."
|
||||
values={{
|
||||
sampleDataInstallLink: (
|
||||
<EuiLink href={sampleDataUrl}>
|
||||
<FormattedMessage
|
||||
id="xpack.graph.listing.createNewGraph.sampleDataInstallLinkText"
|
||||
defaultMessage="sample data"
|
||||
/>
|
||||
</EuiLink>
|
||||
),
|
||||
}}
|
||||
/>
|
||||
</p>
|
||||
</Fragment>
|
||||
}
|
||||
actions={
|
||||
<EuiButton
|
||||
onClick={createItem}
|
||||
fill
|
||||
iconType="plusInCircle"
|
||||
data-test-subj="graphCreateGraphPromptButton"
|
||||
>
|
||||
</p>
|
||||
<p>
|
||||
<FormattedMessage
|
||||
id="xpack.graph.listing.createNewGraph.createButtonLabel"
|
||||
defaultMessage="Create graph"
|
||||
id="xpack.graph.listing.createNewGraph.newToKibanaDescription"
|
||||
defaultMessage="New to Kibana? Get started with {sampleDataInstallLink}."
|
||||
values={{
|
||||
sampleDataInstallLink: (
|
||||
<EuiLink href={sampleDataUrl}>
|
||||
<FormattedMessage
|
||||
id="xpack.graph.listing.createNewGraph.sampleDataInstallLinkText"
|
||||
defaultMessage="sample data"
|
||||
/>
|
||||
</EuiLink>
|
||||
),
|
||||
}}
|
||||
/>
|
||||
</EuiButton>
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
</p>
|
||||
</Fragment>
|
||||
}
|
||||
actions={
|
||||
<EuiButton
|
||||
onClick={createItem}
|
||||
fill
|
||||
iconType="plusInCircle"
|
||||
data-test-subj="graphCreateGraphPromptButton"
|
||||
>
|
||||
<FormattedMessage
|
||||
id="xpack.graph.listing.createNewGraph.createButtonLabel"
|
||||
defaultMessage="Create graph"
|
||||
/>
|
||||
</EuiButton>
|
||||
}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -142,6 +142,9 @@ export function MapsListView() {
|
|||
entityNamePlural={i18n.translate('xpack.maps.mapListing.entityNamePlural', {
|
||||
defaultMessage: 'maps',
|
||||
})}
|
||||
tableCaption={i18n.translate('xpack.maps.mapListing.tableCaption', {
|
||||
defaultMessage: 'Maps',
|
||||
})}
|
||||
tableListTitle={getAppTitle()}
|
||||
toastNotifications={getToasts()}
|
||||
searchFilters={searchFilters}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue