[Embeddables Rebuild] Example aesthetics (#181920)

Slight aesthetic changes to the example embeddables
This commit is contained in:
Devon Thomson 2024-04-29 15:28:48 -04:00 committed by GitHub
parent 2cc5109484
commit 102c207025
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 59 additions and 33 deletions

View file

@ -10,7 +10,7 @@ import { i18n } from '@kbn/i18n';
import { apiIsPresentationContainer } from '@kbn/presentation-containers';
import { EmbeddableApiContext } from '@kbn/presentation-publishing';
import { IncompatibleActionError, UiActionsStart } from '@kbn/ui-actions-plugin/public';
import { addPanelGrouping } from '../add_panel_grouping';
import { embeddableExamplesGrouping } from '../embeddable_examples_grouping';
import { ADD_DATA_TABLE_ACTION_ID, DATA_TABLE_ID } from './constants';
// -----------------------------------------------------------------------------
@ -20,7 +20,7 @@ import { ADD_DATA_TABLE_ACTION_ID, DATA_TABLE_ID } from './constants';
export const registerCreateDataTableAction = (uiActions: UiActionsStart) => {
uiActions.registerAction<EmbeddableApiContext>({
id: ADD_DATA_TABLE_ACTION_ID,
grouping: [addPanelGrouping],
grouping: [embeddableExamplesGrouping],
getIconType: () => 'tableDensityNormal',
isCompatible: async ({ embeddable }) => {
return apiIsPresentationContainer(embeddable);

View file

@ -6,7 +6,8 @@
* Side Public License, v 1.
*/
export const addPanelGrouping = {
export const embeddableExamplesGrouping = {
id: 'embeddableExamples',
getIconType: () => 'documentation',
getDisplayName: () => 'Embeddable examples',
};

View file

@ -10,7 +10,7 @@ import { i18n } from '@kbn/i18n';
import { apiCanAddNewPanel } from '@kbn/presentation-containers';
import { EmbeddableApiContext } from '@kbn/presentation-publishing';
import { IncompatibleActionError, UiActionsStart } from '@kbn/ui-actions-plugin/public';
import { addPanelGrouping } from '../add_panel_grouping';
import { embeddableExamplesGrouping } from '../embeddable_examples_grouping';
import { ADD_EUI_MARKDOWN_ACTION_ID, EUI_MARKDOWN_ID } from './constants';
import { MarkdownEditorSerializedState } from './types';
@ -21,7 +21,7 @@ import { MarkdownEditorSerializedState } from './types';
export const registerCreateEuiMarkdownAction = (uiActions: UiActionsStart) => {
uiActions.registerAction<EmbeddableApiContext>({
id: ADD_EUI_MARKDOWN_ACTION_ID,
grouping: [addPanelGrouping],
grouping: [embeddableExamplesGrouping],
getIconType: () => 'editorCodeBlock',
isCompatible: async ({ embeddable }) => {
return apiCanAddNewPanel(embeddable);

View file

@ -11,14 +11,14 @@ import { apiCanAddNewPanel } from '@kbn/presentation-containers';
import { EmbeddableApiContext } from '@kbn/presentation-publishing';
import { IncompatibleActionError } from '@kbn/ui-actions-plugin/public';
import { UiActionsPublicStart } from '@kbn/ui-actions-plugin/public/plugin';
import { embeddableExamplesGrouping } from '../embeddable_examples_grouping';
import { ADD_FIELD_LIST_ACTION_ID, FIELD_LIST_ID } from './constants';
import { FieldListSerializedStateState } from './types';
import { addPanelGrouping } from '../add_panel_grouping';
export const registerCreateFieldListAction = (uiActions: UiActionsPublicStart) => {
uiActions.registerAction<EmbeddableApiContext>({
id: ADD_FIELD_LIST_ACTION_ID,
grouping: [addPanelGrouping],
grouping: [embeddableExamplesGrouping],
getIconType: () => 'indexOpen',
isCompatible: async ({ embeddable }) => {
return apiCanAddNewPanel(embeddable);

View file

@ -9,14 +9,14 @@
import { apiCanAddNewPanel } from '@kbn/presentation-containers';
import { EmbeddableApiContext } from '@kbn/presentation-publishing';
import { IncompatibleActionError, UiActionsStart } from '@kbn/ui-actions-plugin/public';
import { addPanelGrouping } from '../add_panel_grouping';
import { embeddableExamplesGrouping } from '../embeddable_examples_grouping';
import { ADD_SEARCH_ACTION_ID, SEARCH_EMBEDDABLE_ID } from './constants';
import { SearchSerializedState } from './types';
export const registerAddSearchPanelAction = (uiActions: UiActionsStart) => {
uiActions.registerAction<EmbeddableApiContext>({
id: ADD_SEARCH_ACTION_ID,
grouping: [addPanelGrouping],
grouping: [embeddableExamplesGrouping],
getDisplayName: () => 'Search example',
getIconType: () => 'search',
isCompatible: async ({ embeddable }) => {

View file

@ -6,14 +6,17 @@
* Side Public License, v 1.
*/
import { EuiCallOut } from '@elastic/eui';
import { EuiBadge, EuiStat } from '@elastic/eui';
import { css } from '@emotion/react';
import { DataView } from '@kbn/data-views-plugin/common';
import { ReactEmbeddableFactory } from '@kbn/embeddable-plugin/public';
import { i18n } from '@kbn/i18n';
import {
initializeTimeRange,
fetch$,
initializeTimeRange,
useBatchedPublishingSubjects,
} from '@kbn/presentation-publishing';
import { euiThemeVars } from '@kbn/ui-theme';
import React, { useEffect } from 'react';
import { BehaviorSubject, switchMap, tap } from 'rxjs';
import { SEARCH_EMBEDDABLE_ID } from './constants';
@ -31,10 +34,22 @@ export const getSearchEmbeddableFactory = (services: Services) => {
defaultDataView ? [defaultDataView] : undefined
);
const dataLoading$ = new BehaviorSubject<boolean | undefined>(false);
const blockingError$ = new BehaviorSubject<Error | undefined>(undefined);
if (!defaultDataView) {
blockingError$.next(
new Error(
i18n.translate('embeddableExamples.search.noDataViewError', {
defaultMessage: 'Please install a data view to view this example',
})
)
);
}
const api = buildApi(
{
...timeRange.api,
blockingError: blockingError$,
dataViews: dataViews$,
dataLoading: dataLoading$,
serializeState: () => {
@ -51,7 +66,6 @@ export const getSearchEmbeddableFactory = (services: Services) => {
}
);
const error$ = new BehaviorSubject<Error | undefined>(undefined);
const count$ = new BehaviorSubject<number>(0);
let prevRequestAbortController: AbortController | undefined;
const fetchSubscription = fetch$(api)
@ -62,7 +76,7 @@ export const getSearchEmbeddableFactory = (services: Services) => {
}
}),
switchMap(async (fetchContext) => {
error$.next(undefined);
blockingError$.next(undefined);
if (!defaultDataView) {
return;
}
@ -101,14 +115,14 @@ export const getSearchEmbeddableFactory = (services: Services) => {
count$.next(next.count);
}
if (next && next.hasOwnProperty('error')) {
error$.next(next.error);
blockingError$.next(next.error);
}
});
return {
api,
Component: () => {
const [count, error] = useBatchedPublishingSubjects(count$, error$);
const [count, error] = useBatchedPublishingSubjects(count$, blockingError$);
useEffect(() => {
return () => {
@ -116,26 +130,37 @@ export const getSearchEmbeddableFactory = (services: Services) => {
};
}, []);
if (!defaultDataView) {
return (
<EuiCallOut title="Default data view not found" color="warning" iconType="warning">
<p>Please install a sample data set to run example.</p>
</EuiCallOut>
);
}
if (error) {
return (
<EuiCallOut title="Search error" color="warning" iconType="warning">
<p>{error.message}</p>
</EuiCallOut>
);
}
// in error case we can return null because the panel will handle rendering the blocking error.
if (error || !defaultDataView) return null;
return (
<p>
Found <strong>{count}</strong> from {defaultDataView.name}
</p>
<div
css={css`
width: 100%;
padding: ${euiThemeVars.euiSizeM};
`}
>
<EuiStat
title={count}
titleColor="subdued"
description={
<span>
<EuiBadge iconType="index" color="hollow">
{i18n.translate('embeddableExamples.search.dataViewName', {
defaultMessage: '{dataViewName}',
values: { dataViewName: defaultDataView.name },
})}
</EuiBadge>
</span>
}
titleSize="l"
>
{i18n.translate('embeddableExamples.search.result', {
defaultMessage: '{count, plural, one {document} other {documents}} found',
values: { count },
})}
</EuiStat>
</div>
);
},
};