Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 51 additions & 2 deletions x-pack/examples/embedded_lens_example/public/app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import type {
} from '../../../plugins/lens/public';

import { ViewMode } from '../../../../src/plugins/embeddable/public';
import { ActionExecutionContext } from '../../../../src/plugins/ui_actions/public';

// Generate a Lens state based on some app-specific input parameters.
// `TypedLensByValueInput` can be used for type-safety - it uses the same interfaces as Lens-internal code.
Expand Down Expand Up @@ -126,6 +127,9 @@ export const App = (props: {
to: 'now',
});

const [enableExtraAction, setEnableExtraAction] = useState(false);
const [enableDefaultAction, setEnableDefaultAction] = useState(false);

const LensComponent = props.plugins.lens.EmbeddableComponent;
const LensSaveModalComponent = props.plugins.lens.SaveModalComponent;

Expand Down Expand Up @@ -153,7 +157,7 @@ export const App = (props: {
configuration and navigate to a prefilled editor.
</p>

<EuiFlexGroup>
<EuiFlexGroup wrap>
<EuiFlexItem grow={false}>
<EuiButton
data-test-subj="lns-example-change-color"
Expand Down Expand Up @@ -238,10 +242,34 @@ export const App = (props: {
Change time range
</EuiButton>
</EuiFlexItem>
<EuiFlexItem grow={false}>
<EuiButton
aria-label="Enable extra action"
data-test-subj="lns-example-extra-action"
isDisabled={!attributes}
onClick={() => {
setEnableExtraAction((prevState) => !prevState);
}}
>
{enableExtraAction ? 'Disable extra action' : 'Enable extra action'}
</EuiButton>
</EuiFlexItem>
<EuiFlexItem grow={false}>
<EuiButton
aria-label="Enable default actions"
data-test-subj="lns-example-default-action"
isDisabled={!attributes}
onClick={() => {
setEnableDefaultAction((prevState) => !prevState);
}}
>
{enableDefaultAction ? 'Disable default action' : 'Enable default action'}
</EuiButton>
</EuiFlexItem>
</EuiFlexGroup>
<LensComponent
id=""
withActions
withDefaultActions={enableDefaultAction}
style={{ height: 500 }}
timeRange={time}
attributes={attributes}
Expand All @@ -261,6 +289,27 @@ export const App = (props: {
// call back event for on table row click event
}}
viewMode={ViewMode.VIEW}
extraActions={
enableExtraAction
? [
{
id: 'testAction',
type: 'link',
getIconType: () => 'save',
async isCompatible(
context: ActionExecutionContext<object>
): Promise<boolean> {
return true;
},
execute: async (context: ActionExecutionContext<object>) => {
alert('I am an extra action');
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we want this code here?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, this is a lens embeddable example.

return;
},
getDisplayName: () => 'Extra action',
},
]
: undefined
}
/>
{isSaveModalVisible && (
<LensSaveModalComponent
Expand Down
7 changes: 4 additions & 3 deletions x-pack/examples/exploratory_view_example/kibana.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,14 @@
"server": false,
"ui": true,
"requiredPlugins": [
"observability",
"cases",
"data",
"developerExamples",
"embeddable",
"developerExamples"
"observability"
],
"optionalPlugins": [],
"requiredBundles": [],
"requiredBundles": ["kibanaReact"],
"owner": {
"name": "`Synthetics team`",
"githubTeam": "uptime"
Expand Down
1 change: 1 addition & 0 deletions x-pack/examples/exploratory_view_example/public/app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ export const App = (props: {
attributes={seriesList}
reportType="kpi-over-time"
title={'Monitor response duration'}
withActions={['save', 'explore']}
/>
</EuiPageContentBody>
</EuiPageContent>
Expand Down
17 changes: 12 additions & 5 deletions x-pack/examples/exploratory_view_example/public/mount.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,12 @@

import * as React from 'react';
import { render, unmountComponentAtNode } from 'react-dom';
import { CoreSetup, AppMountParameters } from 'kibana/public';
import { CoreSetup, AppMountParameters, APP_WRAPPER_CLASS } from '../../../../src/core/public';
import { StartDependencies } from './plugin';

import {
KibanaContextProvider,
RedirectAppLinks,
} from '../../../../src/plugins/kibana_react/public';
export const mount =
(coreSetup: CoreSetup<StartDependencies>) =>
async ({ element }: AppMountParameters) => {
Expand All @@ -26,9 +29,13 @@ export const mount =
const i18nCore = core.i18n;

const reactElement = (
<i18nCore.Context>
<App {...deps} defaultIndexPattern={defaultIndexPattern} />
</i18nCore.Context>
<KibanaContextProvider services={{ ...coreSetup, ...core, ...plugins }}>
<i18nCore.Context>
<RedirectAppLinks application={core.application} className={APP_WRAPPER_CLASS}>
<App {...deps} defaultIndexPattern={defaultIndexPattern} />
</RedirectAppLinks>
</i18nCore.Context>
</KibanaContextProvider>
);
render(reactElement, element);
return () => unmountComponentAtNode(element);
Expand Down
23 changes: 19 additions & 4 deletions x-pack/plugins/lens/public/embeddable/embeddable_component.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

import React, { FC, useEffect } from 'react';
import type { CoreStart, ThemeServiceStart } from 'kibana/public';
import type { UiActionsStart } from 'src/plugins/ui_actions/public';
import type { Action, UiActionsStart } from 'src/plugins/ui_actions/public';
import type { Start as InspectorStartContract } from 'src/plugins/inspector/public';
import { EuiLoadingChart } from '@elastic/eui';
import {
Expand Down Expand Up @@ -52,7 +52,8 @@ export type TypedLensByValueInput = Omit<LensByValueInput, 'attributes'> & {
};

export type EmbeddableComponentProps = (TypedLensByValueInput | LensByReferenceInput) & {
withActions?: boolean;
withDefaultActions?: boolean;
extraActions?: Action[];
};

interface PluginsStartDependencies {
Expand All @@ -67,7 +68,9 @@ export function getEmbeddableComponent(core: CoreStart, plugins: PluginsStartDep
const factory = embeddableStart.getEmbeddableFactory('lens')!;
const input = { ...props };
const [embeddable, loading, error] = useEmbeddableFactory({ factory, input });
const hasActions = props.withActions === true;
const hasActions =
Boolean(props.withDefaultActions) || (props.extraActions && props.extraActions?.length > 0);

const theme = core.theme;

if (loading) {
Expand All @@ -83,6 +86,8 @@ export function getEmbeddableComponent(core: CoreStart, plugins: PluginsStartDep
actionPredicate={() => hasActions}
input={input}
theme={theme}
extraActions={props.extraActions}
withDefaultActions={props.withDefaultActions}
/>
);
}
Expand All @@ -98,6 +103,8 @@ interface EmbeddablePanelWrapperProps {
actionPredicate: (id: string) => boolean;
input: EmbeddableComponentProps;
theme: ThemeServiceStart;
extraActions?: Action[];
withDefaultActions?: boolean;
}

const EmbeddablePanelWrapper: FC<EmbeddablePanelWrapperProps> = ({
Expand All @@ -107,6 +114,8 @@ const EmbeddablePanelWrapper: FC<EmbeddablePanelWrapperProps> = ({
inspector,
input,
theme,
extraActions,
withDefaultActions,
}) => {
useEffect(() => {
embeddable.updateInput(input);
Expand All @@ -116,7 +125,13 @@ const EmbeddablePanelWrapper: FC<EmbeddablePanelWrapperProps> = ({
<EmbeddablePanel
hideHeader={false}
embeddable={embeddable as IEmbeddable<EmbeddableInput, EmbeddableOutput>}
getActions={uiActions.getTriggerCompatibleActions}
getActions={async (triggerId, context) => {
const actions = withDefaultActions
? await uiActions.getTriggerCompatibleActions(triggerId, context)
: [];

return [...(extraActions ?? []), ...actions];
}}
inspector={inspector}
actionPredicate={actionPredicate}
showShadow={false}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -783,7 +783,7 @@ export class LensAttributes {
};
}

getJSON(refresh?: number): TypedLensByValueInput['attributes'] {
getJSON(): TypedLensByValueInput['attributes'] {
const uniqueIndexPatternsIds = Array.from(
new Set([...this.layerConfigs.map(({ indexPattern }) => indexPattern.id)])
);
Expand All @@ -792,7 +792,7 @@ export class LensAttributes {

return {
title: 'Prefilled from exploratory view app',
description: String(refresh),
description: '',
visualizationType: 'lnsXY',
references: [
...uniqueIndexPatternsIds.map((patternId) => ({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
* 2.0.
*/
export const sampleAttribute = {
description: 'undefined',
description: '',
references: [
{
id: 'apm-*',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
* 2.0.
*/
export const sampleAttributeCoreWebVital = {
description: 'undefined',
description: '',
references: [
{
id: 'apm-*',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
* 2.0.
*/
export const sampleAttributeKpi = {
description: 'undefined',
description: '',
references: [
{
id: 'apm-*',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,15 +49,30 @@ export function convertToShortUrl(series: SeriesUrl) {
};
}

export function createExploratoryViewRoutePath({
reportType,
allSeries,
}: {
reportType: ReportViewType;
allSeries: AllSeries;
}) {
const allShortSeries: AllShortSeries = allSeries.map((series) => convertToShortUrl(series));

return `/exploratory-view/#?reportType=${reportType}&sr=${rison.encode(
allShortSeries as unknown as RisonValue
)}`;
}

export function createExploratoryViewUrl(
{ reportType, allSeries }: { reportType: ReportViewType; allSeries: AllSeries },
baseHref = ''
baseHref = '',
appId = 'observability'
) {
const allShortSeries: AllShortSeries = allSeries.map((series) => convertToShortUrl(series));

return (
baseHref +
`/app/observability/exploratory-view/#?reportType=${reportType}&sr=${rison.encode(
`/app/${appId}/exploratory-view/#?reportType=${reportType}&sr=${rison.encode(
allShortSeries as unknown as RisonValue
)}`
);
Expand Down
Loading