mirror of
https://github.com/elastic/kibana.git
synced 2025-06-27 10:40:07 -04:00
[Analyst Experience Components] Dashboard & Control Group APIs (#150121)
Aligns the Portable Dashboard renderer and the Control Group renderer to a new API structure using `useImperativeHandle` rather than the overcomplicated and mostly unused wrapper provider system.
This commit is contained in:
parent
befd429f4f
commit
ffc349225e
146 changed files with 2772 additions and 2854 deletions
|
@ -9,11 +9,8 @@
|
|||
import React from 'react';
|
||||
|
||||
import { ViewMode } from '@kbn/embeddable-plugin/public';
|
||||
import { withSuspense } from '@kbn/presentation-util-plugin/public';
|
||||
import { EuiPanel, EuiSpacer, EuiText, EuiTitle } from '@elastic/eui';
|
||||
import { LazyControlGroupRenderer } from '@kbn/controls-plugin/public';
|
||||
|
||||
const ControlGroupRenderer = withSuspense(LazyControlGroupRenderer);
|
||||
import { ControlGroupRenderer } from '@kbn/controls-plugin/public';
|
||||
|
||||
export const AddButtonExample = ({ dataViewId }: { dataViewId: string }) => {
|
||||
return (
|
||||
|
|
|
@ -6,36 +6,18 @@
|
|||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import React, { useMemo, useState } from 'react';
|
||||
import React, { useState } from 'react';
|
||||
|
||||
import {
|
||||
LazyControlGroupRenderer,
|
||||
ControlGroupContainer,
|
||||
useControlGroupContainerContext,
|
||||
ControlStyle,
|
||||
} from '@kbn/controls-plugin/public';
|
||||
import { withSuspense } from '@kbn/presentation-util-plugin/public';
|
||||
import { EuiButtonGroup, EuiPanel, EuiSpacer, EuiText, EuiTitle } from '@elastic/eui';
|
||||
import { ViewMode } from '@kbn/embeddable-plugin/public';
|
||||
|
||||
const ControlGroupRenderer = withSuspense(LazyControlGroupRenderer);
|
||||
import { EuiButtonGroup, EuiPanel, EuiSpacer, EuiText, EuiTitle } from '@elastic/eui';
|
||||
import { ControlGroupRenderer, ControlStyle, ControlGroupAPI } from '@kbn/controls-plugin/public';
|
||||
import { AwaitingControlGroupAPI } from '@kbn/controls-plugin/public/control_group';
|
||||
|
||||
export const BasicReduxExample = ({ dataViewId }: { dataViewId: string }) => {
|
||||
const [controlGroup, setControlGroup] = useState<ControlGroupContainer>();
|
||||
|
||||
const ControlGroupReduxWrapper = useMemo(() => {
|
||||
if (controlGroup) return controlGroup.getReduxEmbeddableTools().Wrapper;
|
||||
}, [controlGroup]);
|
||||
|
||||
const ButtonControls = () => {
|
||||
const {
|
||||
useEmbeddableDispatch,
|
||||
useEmbeddableSelector: select,
|
||||
actions: { setControlStyle },
|
||||
} = useControlGroupContainerContext();
|
||||
const dispatch = useEmbeddableDispatch();
|
||||
const controlStyle = select((state) => state.explicitInput.controlStyle);
|
||||
const [controlGroupAPI, setControlGroupApi] = useState<AwaitingControlGroupAPI>(null);
|
||||
|
||||
const Buttons = ({ api }: { api: ControlGroupAPI }) => {
|
||||
const controlStyle = api.select((state) => state.explicitInput.controlStyle);
|
||||
return (
|
||||
<EuiButtonGroup
|
||||
legend="Text style"
|
||||
|
@ -52,9 +34,7 @@ export const BasicReduxExample = ({ dataViewId }: { dataViewId: string }) => {
|
|||
},
|
||||
]}
|
||||
idSelected={controlStyle}
|
||||
onChange={(id, value) => {
|
||||
dispatch(setControlStyle(value));
|
||||
}}
|
||||
onChange={(id, value) => api.dispatch.setControlStyle(value)}
|
||||
type="single"
|
||||
/>
|
||||
);
|
||||
|
@ -70,16 +50,10 @@ export const BasicReduxExample = ({ dataViewId }: { dataViewId: string }) => {
|
|||
</EuiText>
|
||||
<EuiSpacer size="m" />
|
||||
<EuiPanel hasBorder={true}>
|
||||
{ControlGroupReduxWrapper && (
|
||||
<ControlGroupReduxWrapper>
|
||||
<ButtonControls />
|
||||
</ControlGroupReduxWrapper>
|
||||
)}
|
||||
{controlGroupAPI && <Buttons api={controlGroupAPI} />}
|
||||
|
||||
<ControlGroupRenderer
|
||||
onLoadComplete={async (newControlGroup) => {
|
||||
setControlGroup(newControlGroup);
|
||||
}}
|
||||
ref={setControlGroupApi}
|
||||
getCreationOptions={async (initialInput, builder) => {
|
||||
await builder.addDataControlFromField(initialInput, {
|
||||
dataViewId,
|
||||
|
|
|
@ -23,17 +23,14 @@ import {
|
|||
import { ViewMode } from '@kbn/embeddable-plugin/public';
|
||||
import { OPTIONS_LIST_CONTROL, RANGE_SLIDER_CONTROL } from '@kbn/controls-plugin/common';
|
||||
import {
|
||||
LazyControlGroupRenderer,
|
||||
ControlGroupContainer,
|
||||
ControlGroupInput,
|
||||
type ControlGroupInput,
|
||||
ControlGroupRenderer,
|
||||
AwaitingControlGroupAPI,
|
||||
ACTION_EDIT_CONTROL,
|
||||
ACTION_DELETE_CONTROL,
|
||||
} from '@kbn/controls-plugin/public';
|
||||
import { withSuspense } from '@kbn/presentation-util-plugin/public';
|
||||
import { ControlInputTransform } from '@kbn/controls-plugin/common/types';
|
||||
|
||||
const ControlGroupRenderer = withSuspense(LazyControlGroupRenderer);
|
||||
|
||||
const INPUT_KEY = 'kbnControls:saveExample:input';
|
||||
|
||||
const WITH_CUSTOM_PLACEHOLDER = 'Custom Placeholder';
|
||||
|
@ -41,7 +38,7 @@ const WITH_CUSTOM_PLACEHOLDER = 'Custom Placeholder';
|
|||
export const EditExample = () => {
|
||||
const [isSaving, setIsSaving] = useState(false);
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
const [controlGroup, setControlGroup] = useState<ControlGroupContainer>();
|
||||
const [controlGroupAPI, setControlGroupAPI] = useState<AwaitingControlGroupAPI>(null);
|
||||
const [toggleIconIdToSelectedMapIcon, setToggleIconIdToSelectedMapIcon] = useState<{
|
||||
[id: string]: boolean;
|
||||
}>({});
|
||||
|
@ -54,20 +51,21 @@ export const EditExample = () => {
|
|||
},
|
||||
};
|
||||
|
||||
if (controlGroup) {
|
||||
if (controlGroupAPI) {
|
||||
const disabledActions: string[] = Object.keys(
|
||||
pickBy(newToggleIconIdToSelectedMapIcon, (value) => value)
|
||||
);
|
||||
controlGroup.updateInput({ disabledActions });
|
||||
controlGroupAPI.updateInput({ disabledActions });
|
||||
}
|
||||
|
||||
setToggleIconIdToSelectedMapIcon(newToggleIconIdToSelectedMapIcon);
|
||||
}
|
||||
|
||||
async function onSave() {
|
||||
setIsSaving(true);
|
||||
if (!controlGroupAPI) return;
|
||||
|
||||
localStorage.setItem(INPUT_KEY, JSON.stringify(controlGroup!.getInput()));
|
||||
setIsSaving(true);
|
||||
localStorage.setItem(INPUT_KEY, JSON.stringify(controlGroupAPI.getInput()));
|
||||
|
||||
// simulated async save await
|
||||
await new Promise((resolve) => setTimeout(resolve, 1000));
|
||||
|
@ -133,9 +131,9 @@ export const EditExample = () => {
|
|||
<EuiButtonEmpty
|
||||
color="primary"
|
||||
iconType="plusInCircle"
|
||||
isDisabled={controlGroup === undefined}
|
||||
isDisabled={controlGroupAPI === undefined}
|
||||
onClick={() => {
|
||||
controlGroup!.openAddDataControlFlyout(controlInputTransform);
|
||||
controlGroupAPI!.openAddDataControlFlyout(controlInputTransform);
|
||||
}}
|
||||
>
|
||||
Add control
|
||||
|
@ -171,7 +169,7 @@ export const EditExample = () => {
|
|||
<EuiButton
|
||||
fill
|
||||
color="primary"
|
||||
isDisabled={controlGroup === undefined || isSaving}
|
||||
isDisabled={controlGroupAPI === undefined || isSaving}
|
||||
onClick={onSave}
|
||||
isLoading={isSaving}
|
||||
>
|
||||
|
@ -186,6 +184,7 @@ export const EditExample = () => {
|
|||
</>
|
||||
) : null}
|
||||
<ControlGroupRenderer
|
||||
ref={setControlGroupAPI}
|
||||
getCreationOptions={async (initialInput, builder) => {
|
||||
const persistedInput = await onLoad();
|
||||
return {
|
||||
|
@ -196,9 +195,6 @@ export const EditExample = () => {
|
|||
},
|
||||
};
|
||||
}}
|
||||
onLoadComplete={async (newControlGroup) => {
|
||||
setControlGroup(newControlGroup);
|
||||
}}
|
||||
/>
|
||||
</EuiPanel>
|
||||
</>
|
||||
|
|
|
@ -22,12 +22,9 @@ import {
|
|||
EuiText,
|
||||
EuiTitle,
|
||||
} from '@elastic/eui';
|
||||
import { LazyControlGroupRenderer, ControlGroupContainer } from '@kbn/controls-plugin/public';
|
||||
import { withSuspense } from '@kbn/presentation-util-plugin/public';
|
||||
import { AwaitingControlGroupAPI, ControlGroupRenderer } from '@kbn/controls-plugin/public';
|
||||
import { PLUGIN_ID } from './constants';
|
||||
|
||||
const ControlGroupRenderer = withSuspense(LazyControlGroupRenderer);
|
||||
|
||||
interface Props {
|
||||
data: DataPublicPluginStart;
|
||||
dataView: DataView;
|
||||
|
@ -36,7 +33,7 @@ interface Props {
|
|||
|
||||
export const SearchExample = ({ data, dataView, navigation }: Props) => {
|
||||
const [controlFilters, setControlFilters] = useState<Filter[]>([]);
|
||||
const [controlGroup, setControlGroup] = useState<ControlGroupContainer>();
|
||||
const [controlGroupAPI, setControlGroupAPI] = useState<AwaitingControlGroupAPI>();
|
||||
const [hits, setHits] = useState(0);
|
||||
const [filters, setFilters] = useState<Filter[]>([]);
|
||||
const [isSearching, setIsSearching] = useState(false);
|
||||
|
@ -47,16 +44,16 @@ export const SearchExample = ({ data, dataView, navigation }: Props) => {
|
|||
const [timeRange, setTimeRange] = useState<TimeRange>({ from: 'now-7d', to: 'now' });
|
||||
|
||||
useEffect(() => {
|
||||
if (!controlGroup) {
|
||||
if (!controlGroupAPI) {
|
||||
return;
|
||||
}
|
||||
const subscription = controlGroup.onFiltersPublished$.subscribe((newFilters) => {
|
||||
const subscription = controlGroupAPI.onFiltersPublished$.subscribe((newFilters) => {
|
||||
setControlFilters([...newFilters]);
|
||||
});
|
||||
return () => {
|
||||
subscription.unsubscribe();
|
||||
};
|
||||
}, [controlGroup]);
|
||||
}, [controlGroupAPI]);
|
||||
|
||||
useEffect(() => {
|
||||
const abortController = new AbortController();
|
||||
|
@ -155,10 +152,8 @@ export const SearchExample = ({ data, dataView, navigation }: Props) => {
|
|||
},
|
||||
};
|
||||
}}
|
||||
onLoadComplete={async (newControlGroup) => {
|
||||
setControlGroup(newControlGroup);
|
||||
}}
|
||||
query={query}
|
||||
ref={setControlGroupAPI}
|
||||
timeRange={timeRange}
|
||||
/>
|
||||
<EuiCallOut title="Search results">
|
||||
|
|
|
@ -18,10 +18,9 @@
|
|||
"@kbn/data-plugin",
|
||||
"@kbn/controls-plugin",
|
||||
"@kbn/navigation-plugin",
|
||||
"@kbn/presentation-util-plugin",
|
||||
"@kbn/shared-ux-page-kibana-template",
|
||||
"@kbn/embeddable-plugin",
|
||||
"@kbn/data-views-plugin",
|
||||
"@kbn/es-query"
|
||||
"@kbn/es-query",
|
||||
]
|
||||
}
|
||||
|
|
|
@ -20,7 +20,6 @@
|
|||
"unifiedSearch",
|
||||
"developerExamples",
|
||||
"embeddableExamples"
|
||||
],
|
||||
"requiredBundles": ["presentationUtil"]
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,19 +6,37 @@
|
|||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
|
||||
import { withSuspense } from '@kbn/shared-ux-utility';
|
||||
import { ViewMode } from '@kbn/embeddable-plugin/public';
|
||||
import type { DataView } from '@kbn/data-views-plugin/public';
|
||||
import { controlGroupInputBuilder } from '@kbn/controls-plugin/public';
|
||||
import { EuiPanel, EuiSpacer, EuiText, EuiTitle } from '@elastic/eui';
|
||||
import { controlGroupInputBuilder } from '@kbn/controls-plugin/public';
|
||||
import { getDefaultControlGroupInput } from '@kbn/controls-plugin/common';
|
||||
import { FILTER_DEBUGGER_EMBEDDABLE } from '@kbn/embeddable-examples-plugin/public';
|
||||
import { LazyDashboardContainerRenderer } from '@kbn/dashboard-plugin/public';
|
||||
|
||||
const DashboardContainerRenderer = withSuspense(LazyDashboardContainerRenderer);
|
||||
import { AwaitingDashboardAPI, DashboardRenderer } from '@kbn/dashboard-plugin/public';
|
||||
|
||||
export const DashboardWithControlsExample = ({ dataView }: { dataView: DataView }) => {
|
||||
const [dashboard, setDashboard] = useState<AwaitingDashboardAPI>();
|
||||
|
||||
// add a filter debugger panel as soon as the dashboard becomes available
|
||||
useEffect(() => {
|
||||
if (!dashboard) return;
|
||||
(async () => {
|
||||
const embeddable = await dashboard.addNewEmbeddable(FILTER_DEBUGGER_EMBEDDABLE, {});
|
||||
const prevPanelState = dashboard.getExplicitInput().panels[embeddable.id];
|
||||
// resize the new panel so that it fills up the entire width of the dashboard
|
||||
dashboard.updateInput({
|
||||
panels: {
|
||||
[embeddable.id]: {
|
||||
...prevPanelState,
|
||||
gridData: { i: embeddable.id, x: 0, y: 0, w: 48, h: 12 },
|
||||
},
|
||||
},
|
||||
});
|
||||
})();
|
||||
}, [dashboard]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<EuiTitle>
|
||||
|
@ -29,10 +47,10 @@ export const DashboardWithControlsExample = ({ dataView }: { dataView: DataView
|
|||
</EuiText>
|
||||
<EuiSpacer size="m" />
|
||||
<EuiPanel hasBorder={true}>
|
||||
<DashboardContainerRenderer
|
||||
<DashboardRenderer
|
||||
getCreationOptions={async () => {
|
||||
const builder = controlGroupInputBuilder;
|
||||
const controlGroupInput = {};
|
||||
const controlGroupInput = getDefaultControlGroupInput();
|
||||
await builder.addDataControlFromField(controlGroupInput, {
|
||||
dataViewId: dataView.id ?? '',
|
||||
title: 'Destintion country',
|
||||
|
@ -57,22 +75,7 @@ export const DashboardWithControlsExample = ({ dataView }: { dataView: DataView
|
|||
},
|
||||
};
|
||||
}}
|
||||
onDashboardContainerLoaded={(container) => {
|
||||
const addFilterEmbeddable = async () => {
|
||||
const embeddable = await container.addNewEmbeddable(FILTER_DEBUGGER_EMBEDDABLE, {});
|
||||
const prevPanelState = container.getExplicitInput().panels[embeddable.id];
|
||||
// resize the new panel so that it fills up the entire width of the dashboard
|
||||
container.updateInput({
|
||||
panels: {
|
||||
[embeddable.id]: {
|
||||
...prevPanelState,
|
||||
gridData: { i: embeddable.id, x: 0, y: 0, w: 48, h: 12 },
|
||||
},
|
||||
},
|
||||
});
|
||||
};
|
||||
addFilterEmbeddable();
|
||||
}}
|
||||
ref={setDashboard}
|
||||
/>
|
||||
</EuiPanel>
|
||||
</>
|
||||
|
|
|
@ -6,9 +6,8 @@
|
|||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import React, { useMemo, useState } from 'react';
|
||||
import React, { useState } from 'react';
|
||||
|
||||
import { DashboardContainer, LazyDashboardContainerRenderer } from '@kbn/dashboard-plugin/public';
|
||||
import {
|
||||
EuiButtonGroup,
|
||||
EuiFlexGroup,
|
||||
|
@ -18,35 +17,19 @@ import {
|
|||
EuiText,
|
||||
EuiTitle,
|
||||
} from '@elastic/eui';
|
||||
import {
|
||||
AwaitingDashboardAPI,
|
||||
DashboardAPI,
|
||||
DashboardRenderer,
|
||||
} from '@kbn/dashboard-plugin/public';
|
||||
import { ViewMode } from '@kbn/embeddable-plugin/public';
|
||||
import { withSuspense } from '@kbn/presentation-util-plugin/public';
|
||||
import { useDashboardContainerContext } from '@kbn/dashboard-plugin/public';
|
||||
|
||||
const DashboardContainerRenderer = withSuspense(LazyDashboardContainerRenderer);
|
||||
|
||||
export const DualReduxExample = () => {
|
||||
const [firstDashboardContainer, setFirstDashboardContainer] = useState<
|
||||
DashboardContainer | undefined
|
||||
>();
|
||||
const [secondDashboardContainer, setSecondDashboardContainer] = useState<
|
||||
DashboardContainer | undefined
|
||||
>();
|
||||
const [firstDashboardContainer, setFirstDashboardContainer] = useState<AwaitingDashboardAPI>();
|
||||
const [secondDashboardContainer, setSecondDashboardContainer] = useState<AwaitingDashboardAPI>();
|
||||
|
||||
const FirstDashboardReduxWrapper = useMemo(() => {
|
||||
if (firstDashboardContainer) return firstDashboardContainer.getReduxEmbeddableTools().Wrapper;
|
||||
}, [firstDashboardContainer]);
|
||||
const SecondDashboardReduxWrapper = useMemo(() => {
|
||||
if (secondDashboardContainer) return secondDashboardContainer.getReduxEmbeddableTools().Wrapper;
|
||||
}, [secondDashboardContainer]);
|
||||
|
||||
const ButtonControls = () => {
|
||||
const {
|
||||
useEmbeddableDispatch,
|
||||
useEmbeddableSelector: select,
|
||||
actions: { setViewMode },
|
||||
} = useDashboardContainerContext();
|
||||
const dispatch = useEmbeddableDispatch();
|
||||
const viewMode = select((state) => state.explicitInput.viewMode);
|
||||
const ButtonControls = ({ dashboard }: { dashboard: DashboardAPI }) => {
|
||||
const viewMode = dashboard.select((state) => state.explicitInput.viewMode);
|
||||
|
||||
return (
|
||||
<EuiButtonGroup
|
||||
|
@ -64,9 +47,7 @@ export const DualReduxExample = () => {
|
|||
},
|
||||
]}
|
||||
idSelected={viewMode}
|
||||
onChange={(id, value) => {
|
||||
dispatch(setViewMode(value));
|
||||
}}
|
||||
onChange={(id, value) => dashboard.dispatch.setViewMode(value)}
|
||||
type="single"
|
||||
/>
|
||||
);
|
||||
|
@ -91,34 +72,18 @@ export const DualReduxExample = () => {
|
|||
<h3>Dashboard #1</h3>
|
||||
</EuiTitle>
|
||||
<EuiSpacer size="m" />
|
||||
{FirstDashboardReduxWrapper && (
|
||||
<FirstDashboardReduxWrapper>
|
||||
<ButtonControls />
|
||||
</FirstDashboardReduxWrapper>
|
||||
)}
|
||||
{firstDashboardContainer && <ButtonControls dashboard={firstDashboardContainer} />}
|
||||
<EuiSpacer size="m" />
|
||||
<DashboardContainerRenderer
|
||||
onDashboardContainerLoaded={(container) => {
|
||||
setFirstDashboardContainer(container);
|
||||
}}
|
||||
/>
|
||||
<DashboardRenderer ref={setFirstDashboardContainer} />
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem>
|
||||
<EuiTitle size="xs">
|
||||
<h3>Dashboard #2</h3>
|
||||
</EuiTitle>
|
||||
<EuiSpacer size="m" />
|
||||
{SecondDashboardReduxWrapper && (
|
||||
<SecondDashboardReduxWrapper>
|
||||
<ButtonControls />
|
||||
</SecondDashboardReduxWrapper>
|
||||
)}
|
||||
{secondDashboardContainer && <ButtonControls dashboard={secondDashboardContainer} />}
|
||||
<EuiSpacer size="m" />
|
||||
<DashboardContainerRenderer
|
||||
onDashboardContainerLoaded={(container) => {
|
||||
setSecondDashboardContainer(container);
|
||||
}}
|
||||
/>
|
||||
<DashboardRenderer ref={setSecondDashboardContainer} />
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
</EuiPanel>
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
import React, { useMemo, useState } from 'react';
|
||||
|
||||
import { DashboardContainer, LazyDashboardContainerRenderer } from '@kbn/dashboard-plugin/public';
|
||||
import { AwaitingDashboardAPI, DashboardRenderer } from '@kbn/dashboard-plugin/public';
|
||||
import {
|
||||
EuiButton,
|
||||
EuiFlexGroup,
|
||||
|
@ -23,19 +23,17 @@ import {
|
|||
VisualizeInput,
|
||||
VisualizeOutput,
|
||||
} from '@kbn/visualizations-plugin/public/embeddable/visualize_embeddable';
|
||||
import { withSuspense } from '@kbn/presentation-util-plugin/public';
|
||||
|
||||
const INPUT_KEY = 'portableDashboard:saveExample:input';
|
||||
|
||||
const DashboardContainerRenderer = withSuspense(LazyDashboardContainerRenderer); // make this so we don't have two loading states - loading in the dashboard plugin instead
|
||||
|
||||
export const DynamicByReferenceExample = () => {
|
||||
const [isSaving, setIsSaving] = useState(false);
|
||||
const [dashboardContainer, setDashboardContainer] = useState<DashboardContainer | undefined>();
|
||||
const [dashboard, setdashboard] = useState<AwaitingDashboardAPI>();
|
||||
|
||||
const onSave = async () => {
|
||||
if (!dashboard) return;
|
||||
setIsSaving(true);
|
||||
localStorage.setItem(INPUT_KEY, JSON.stringify(dashboardContainer!.getInput()));
|
||||
localStorage.setItem(INPUT_KEY, JSON.stringify(dashboard.getInput()));
|
||||
// simulated async save await
|
||||
await new Promise((resolve) => setTimeout(resolve, 1000));
|
||||
setIsSaving(false);
|
||||
|
@ -56,44 +54,37 @@ export const DynamicByReferenceExample = () => {
|
|||
|
||||
const resetPersistableInput = () => {
|
||||
localStorage.removeItem(INPUT_KEY);
|
||||
if (dashboardContainer) {
|
||||
const children = dashboardContainer.getChildIds();
|
||||
if (dashboard) {
|
||||
const children = dashboard.getChildIds();
|
||||
children.map((childId) => {
|
||||
dashboardContainer.removeEmbeddable(childId);
|
||||
dashboard.removeEmbeddable(childId);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const addByReference = () => {
|
||||
if (dashboardContainer) {
|
||||
dashboardContainer.addFromLibrary();
|
||||
}
|
||||
};
|
||||
|
||||
const addByValue = async () => {
|
||||
if (dashboardContainer) {
|
||||
dashboardContainer.addNewEmbeddable<VisualizeInput, VisualizeOutput, VisualizeEmbeddable>(
|
||||
'visualization',
|
||||
{
|
||||
title: 'Sample Markdown Vis',
|
||||
savedVis: {
|
||||
type: 'markdown',
|
||||
title: '',
|
||||
data: { aggs: [], searchSource: {} },
|
||||
params: {
|
||||
fontSize: 12,
|
||||
openLinksInNewTab: false,
|
||||
markdown: '### By Value Visualization\nThis is a sample by value panel.',
|
||||
},
|
||||
if (!dashboard) return;
|
||||
dashboard.addNewEmbeddable<VisualizeInput, VisualizeOutput, VisualizeEmbeddable>(
|
||||
'visualization',
|
||||
{
|
||||
title: 'Sample Markdown Vis',
|
||||
savedVis: {
|
||||
type: 'markdown',
|
||||
title: '',
|
||||
data: { aggs: [], searchSource: {} },
|
||||
params: {
|
||||
fontSize: 12,
|
||||
openLinksInNewTab: false,
|
||||
markdown: '### By Value Visualization\nThis is a sample by value panel.',
|
||||
},
|
||||
}
|
||||
);
|
||||
}
|
||||
},
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
const disableButtons = useMemo(() => {
|
||||
return dashboardContainer === undefined || isSaving;
|
||||
}, [dashboardContainer, isSaving]);
|
||||
return !dashboard || isSaving;
|
||||
}, [dashboard, isSaving]);
|
||||
|
||||
return (
|
||||
<>
|
||||
|
@ -114,7 +105,7 @@ export const DynamicByReferenceExample = () => {
|
|||
</EuiButton>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem>
|
||||
<EuiButton onClick={addByReference} isDisabled={disableButtons}>
|
||||
<EuiButton onClick={() => dashboard?.addFromLibrary()} isDisabled={disableButtons}>
|
||||
Add visualization from library
|
||||
</EuiButton>
|
||||
</EuiFlexItem>
|
||||
|
@ -141,7 +132,7 @@ export const DynamicByReferenceExample = () => {
|
|||
</EuiFlexGroup>
|
||||
<EuiSpacer size="m" />
|
||||
|
||||
<DashboardContainerRenderer
|
||||
<DashboardRenderer
|
||||
getCreationOptions={async () => {
|
||||
const persistedInput = getPersistableInput();
|
||||
return {
|
||||
|
@ -151,9 +142,7 @@ export const DynamicByReferenceExample = () => {
|
|||
},
|
||||
};
|
||||
}}
|
||||
onDashboardContainerLoaded={(container) => {
|
||||
setDashboardContainer(container);
|
||||
}}
|
||||
ref={setdashboard}
|
||||
/>
|
||||
</EuiPanel>
|
||||
</>
|
||||
|
|
|
@ -11,15 +11,9 @@ import { css } from '@emotion/react';
|
|||
|
||||
import { buildPhraseFilter, Filter } from '@kbn/es-query';
|
||||
import type { DataView } from '@kbn/data-views-plugin/public';
|
||||
import {
|
||||
LazyDashboardContainerRenderer,
|
||||
DashboardCreationOptions,
|
||||
} from '@kbn/dashboard-plugin/public';
|
||||
import { DashboardRenderer, DashboardCreationOptions } from '@kbn/dashboard-plugin/public';
|
||||
import { EuiCode, EuiPanel, EuiSpacer, EuiText, EuiTitle } from '@elastic/eui';
|
||||
import { ViewMode } from '@kbn/embeddable-plugin/public';
|
||||
import { withSuspense } from '@kbn/presentation-util-plugin/public';
|
||||
|
||||
const DashboardContainerRenderer = withSuspense(LazyDashboardContainerRenderer);
|
||||
|
||||
export const StaticByReferenceExample = ({
|
||||
dashboardId,
|
||||
|
@ -50,7 +44,7 @@ export const StaticByReferenceExample = ({
|
|||
overflow-y: auto;
|
||||
`}
|
||||
>
|
||||
<DashboardContainerRenderer
|
||||
<DashboardRenderer
|
||||
savedObjectId={dashboardId}
|
||||
getCreationOptions={async () => {
|
||||
const field = dataView.getFieldByName('machine.os.keyword');
|
||||
|
@ -61,13 +55,10 @@ export const StaticByReferenceExample = ({
|
|||
if (field) {
|
||||
filter = buildPhraseFilter(field, 'win xp', dataView);
|
||||
filter.meta.negate = true;
|
||||
creationOptions = { ...creationOptions, overrideInput: { filters: [filter] } };
|
||||
creationOptions = { ...creationOptions, initialInput: { filters: [filter] } };
|
||||
}
|
||||
return creationOptions; // if can't find the field, then just return no special creation options
|
||||
}}
|
||||
onDashboardContainerLoaded={(container) => {
|
||||
return; // this example is static, so don't need to do anything with the dashboard container
|
||||
}}
|
||||
/>
|
||||
</EuiPanel>
|
||||
</>
|
||||
|
|
|
@ -11,13 +11,10 @@ import React from 'react';
|
|||
import { ViewMode } from '@kbn/embeddable-plugin/public';
|
||||
import { EuiPanel, EuiSpacer, EuiText, EuiTitle } from '@elastic/eui';
|
||||
import type { DashboardPanelMap } from '@kbn/dashboard-plugin/common';
|
||||
import { LazyDashboardContainerRenderer } from '@kbn/dashboard-plugin/public';
|
||||
import { withSuspense } from '@kbn/presentation-util-plugin/public';
|
||||
import { DashboardRenderer } from '@kbn/dashboard-plugin/public';
|
||||
|
||||
import panelsJson from './static_by_value_example_panels.json';
|
||||
|
||||
const DashboardContainerRenderer = withSuspense(LazyDashboardContainerRenderer);
|
||||
|
||||
export const StaticByValueExample = () => {
|
||||
return (
|
||||
<>
|
||||
|
@ -29,7 +26,7 @@ export const StaticByValueExample = () => {
|
|||
</EuiText>
|
||||
<EuiSpacer size="m" />
|
||||
<EuiPanel hasBorder={true}>
|
||||
<DashboardContainerRenderer
|
||||
<DashboardRenderer
|
||||
getCreationOptions={async () => {
|
||||
return {
|
||||
initialInput: {
|
||||
|
@ -39,9 +36,6 @@ export const StaticByValueExample = () => {
|
|||
},
|
||||
};
|
||||
}}
|
||||
onDashboardContainerLoaded={(container) => {
|
||||
return; // this example is static, so don't need to do anything with the dashboard container
|
||||
}}
|
||||
/>
|
||||
</EuiPanel>
|
||||
</>
|
||||
|
|
|
@ -20,11 +20,9 @@
|
|||
"@kbn/embeddable-plugin",
|
||||
"@kbn/data-views-plugin",
|
||||
"@kbn/visualizations-plugin",
|
||||
"@kbn/presentation-util-plugin",
|
||||
"@kbn/developer-examples-plugin",
|
||||
"@kbn/embeddable-examples-plugin",
|
||||
"@kbn/shared-ux-page-kibana-template",
|
||||
"@kbn/shared-ux-utility",
|
||||
"@kbn/controls-plugin",
|
||||
"@kbn/shared-ux-router"
|
||||
]
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue