Skip to content

Commit

Permalink
[8.x] [dashboard] Lazy DashboardRenderer (#192754) (#193219)
Browse files Browse the repository at this point in the history
# Backport

This will backport the following commits from `main` to `8.x`:
- [[dashboard] Lazy DashboardRenderer
(#192754)](#192754)

<!--- Backport version: 8.9.8 -->

### Questions ?
Please refer to the [Backport tool
documentation](https://github.com/sqren/backport)

<!--BACKPORT [{"author":{"name":"Nathan
Reese","email":"[email protected]"},"sourceCommit":{"committedDate":"2024-09-17T19:15:50Z","message":"[dashboard]
Lazy DashboardRenderer (#192754)\n\nChanges\r\n1. expose
DashboardRenderer as lazy loaded component to reduce static\r\npage load
size\r\n2. Use `onApiAvailable` prop to pass DashboardApi to parent
instead of\r\n`forwardRef`\r\n3. Decouple DashboardApi from legacy
embeddable system. This changed\r\nfunctions such as `updateInput` and
using redux `select` to
access\r\nstate.\r\n\r\n---------\r\n\r\nCo-authored-by: kibanamachine
<[email protected]>\r\nCo-authored-by:
Elastic Machine
<[email protected]>","sha":"e2380afd7b72912713c2372084463ced489bedb7","branchLabelMapping":{"^v9.0.0$":"main","^v8.16.0$":"8.x","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["Feature:Embedding","Team:Presentation","release_note:skip","v9.0.0","ci:project-deploy-observability","Team:obs-ux-infra_services","apm:review","project:embeddableRebuild","v8.16.0"],"number":192754,"url":"#192754
Lazy DashboardRenderer (#192754)\n\nChanges\r\n1. expose
DashboardRenderer as lazy loaded component to reduce static\r\npage load
size\r\n2. Use `onApiAvailable` prop to pass DashboardApi to parent
instead of\r\n`forwardRef`\r\n3. Decouple DashboardApi from legacy
embeddable system. This changed\r\nfunctions such as `updateInput` and
using redux `select` to
access\r\nstate.\r\n\r\n---------\r\n\r\nCo-authored-by: kibanamachine
<[email protected]>\r\nCo-authored-by:
Elastic Machine
<[email protected]>","sha":"e2380afd7b72912713c2372084463ced489bedb7"}},"sourceBranch":"main","suggestedTargetBranches":["8.x"],"targetPullRequestStates":[{"branch":"main","label":"v9.0.0","labelRegex":"^v9.0.0$","isSourceBranch":true,"state":"MERGED","url":"#192754
Lazy DashboardRenderer (#192754)\n\nChanges\r\n1. expose
DashboardRenderer as lazy loaded component to reduce static\r\npage load
size\r\n2. Use `onApiAvailable` prop to pass DashboardApi to parent
instead of\r\n`forwardRef`\r\n3. Decouple DashboardApi from legacy
embeddable system. This changed\r\nfunctions such as `updateInput` and
using redux `select` to
access\r\nstate.\r\n\r\n---------\r\n\r\nCo-authored-by: kibanamachine
<[email protected]>\r\nCo-authored-by:
Elastic Machine
<[email protected]>","sha":"e2380afd7b72912713c2372084463ced489bedb7"}},{"branch":"8.x","label":"v8.16.0","labelRegex":"^v8.16.0$","isSourceBranch":false,"state":"NOT_CREATED"}]}]
BACKPORT-->

---------

Co-authored-by: kibanamachine <[email protected]>
  • Loading branch information
nreese and kibanamachine committed Sep 18, 2024
1 parent 73ac7f0 commit 79cb9c5
Show file tree
Hide file tree
Showing 45 changed files with 673 additions and 742 deletions.
48 changes: 28 additions & 20 deletions examples/portable_dashboards_example/public/app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,55 +12,65 @@ import React, { useMemo } from 'react';
import { useAsync } from 'react-use/lib';
import { Redirect } from 'react-router-dom';
import { Router, Routes, Route } from '@kbn/shared-ux-router';
import { AppMountParameters } from '@kbn/core/public';
import { AppMountParameters, CoreStart } from '@kbn/core/public';
import { EuiButton, EuiCallOut, EuiSpacer } from '@elastic/eui';
import { DashboardListingTable } from '@kbn/dashboard-plugin/public';
import { KibanaPageTemplate } from '@kbn/shared-ux-page-kibana-template';

import { DualReduxExample } from './dual_redux_example';
import { KibanaRenderContextProvider } from '@kbn/react-kibana-context-render';
import { DualDashboardsExample } from './dual_dashboards_example';
import { StartDeps } from './plugin';
import { StaticByValueExample } from './static_by_value_example';
import { StaticByReferenceExample } from './static_by_reference_example';
import { DynamicByReferenceExample } from './dynamically_add_panels_example';
import { DashboardWithControlsExample } from './dashboard_with_controls_example';

const DASHBOARD_DEMO_PATH = '/dashboardDemo';
const DASHBOARD_LIST_PATH = '/listingDemo';

export const renderApp = async (
coreStart: CoreStart,
{ data, dashboard }: StartDeps,
{ element, history }: AppMountParameters
) => {
ReactDOM.render(
<PortableDashboardsDemos data={data} history={history} dashboard={dashboard} />,
<PortableDashboardsDemos
coreStart={coreStart}
data={data}
history={history}
dashboard={dashboard}
/>,
element
);
return () => ReactDOM.unmountComponentAtNode(element);
};

const PortableDashboardsDemos = ({
coreStart,
data,
dashboard,
history,
}: {
coreStart: CoreStart;
data: StartDeps['data'];
dashboard: StartDeps['dashboard'];
history: AppMountParameters['history'];
}) => {
return (
<Router history={history}>
<Routes>
<Route exact path="/">
<Redirect to={DASHBOARD_DEMO_PATH} />
</Route>
<Route path={DASHBOARD_LIST_PATH}>
<PortableDashboardListingDemo history={history} />
</Route>
<Route path={DASHBOARD_DEMO_PATH}>
<DashboardsDemo data={data} dashboard={dashboard} history={history} />
</Route>
</Routes>
</Router>
<KibanaRenderContextProvider i18n={coreStart.i18n} theme={coreStart.theme}>
<Router history={history}>
<Routes>
<Route exact path="/">
<Redirect to={DASHBOARD_DEMO_PATH} />
</Route>
<Route path={DASHBOARD_LIST_PATH}>
<PortableDashboardListingDemo history={history} />
</Route>
<Route path={DASHBOARD_DEMO_PATH}>
<DashboardsDemo data={data} dashboard={dashboard} history={history} />
</Route>
</Routes>
</Router>
</KibanaRenderContextProvider>
);
};

Expand Down Expand Up @@ -91,9 +101,7 @@ const DashboardsDemo = ({
<>
<DashboardWithControlsExample dataView={dataViews[0]} />
<EuiSpacer size="xl" />
<DynamicByReferenceExample />
<EuiSpacer size="xl" />
<DualReduxExample />
<DualDashboardsExample />
<EuiSpacer size="xl" />
<StaticByReferenceExample dashboardId={logsSampleDashboardId} dataView={dataViews[0]} />
<EuiSpacer size="xl" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,41 +14,29 @@ import type { DataView } from '@kbn/data-views-plugin/public';
import { EuiPanel, EuiSpacer, EuiText, EuiTitle } from '@elastic/eui';
import { controlGroupStateBuilder } from '@kbn/controls-plugin/public';
import {
AwaitingDashboardAPI,
DashboardApi,
DashboardRenderer,
DashboardCreationOptions,
} from '@kbn/dashboard-plugin/public';
import { apiHasUniqueId } from '@kbn/presentation-publishing';
import { FILTER_DEBUGGER_EMBEDDABLE_ID } from './constants';

export const DashboardWithControlsExample = ({ dataView }: { dataView: DataView }) => {
const [dashboard, setDashboard] = useState<AwaitingDashboardAPI>();
const [dashboard, setDashboard] = useState<DashboardApi | undefined>();

// add a filter debugger panel as soon as the dashboard becomes available
useEffect(() => {
if (!dashboard) return;
(async () => {
const api = await dashboard.addNewPanel(
dashboard
.addNewPanel(
{
panelType: FILTER_DEBUGGER_EMBEDDABLE_ID,
initialState: {},
},
true
);
if (!apiHasUniqueId(api)) {
return;
}
const prevPanelState = dashboard.getExplicitInput().panels[api.uuid];
// resize the new panel so that it fills up the entire width of the dashboard
dashboard.updateInput({
panels: {
[api.uuid]: {
...prevPanelState,
gridData: { i: api.uuid, x: 0, y: 0, w: 48, h: 12 },
},
},
)
.catch(() => {
// ignore error - its an example
});
})();
}, [dashboard]);

return (
Expand Down Expand Up @@ -88,7 +76,7 @@ export const DashboardWithControlsExample = ({ dataView }: { dataView: DataView
}),
};
}}
ref={setDashboard}
onApiAvailable={setDashboard}
/>
</EuiPanel>
</>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,19 +18,16 @@ import {
EuiText,
EuiTitle,
} from '@elastic/eui';
import {
AwaitingDashboardAPI,
DashboardAPI,
DashboardRenderer,
} from '@kbn/dashboard-plugin/public';
import { DashboardApi, DashboardRenderer } from '@kbn/dashboard-plugin/public';
import { ViewMode } from '@kbn/embeddable-plugin/public';
import { useStateFromPublishingSubject } from '@kbn/presentation-publishing';

export const DualReduxExample = () => {
const [firstDashboardContainer, setFirstDashboardContainer] = useState<AwaitingDashboardAPI>();
const [secondDashboardContainer, setSecondDashboardContainer] = useState<AwaitingDashboardAPI>();
export const DualDashboardsExample = () => {
const [firstDashboardApi, setFirstDashboardApi] = useState<DashboardApi | undefined>();
const [secondDashboardApi, setSecondDashboardApi] = useState<DashboardApi | undefined>();

const ButtonControls = ({ dashboard }: { dashboard: DashboardAPI }) => {
const viewMode = dashboard.select((state) => state.explicitInput.viewMode);
const ButtonControls = ({ dashboardApi }: { dashboardApi: DashboardApi }) => {
const viewMode = useStateFromPublishingSubject(dashboardApi.viewMode);

return (
<EuiButtonGroup
Expand All @@ -48,7 +45,7 @@ export const DualReduxExample = () => {
},
]}
idSelected={viewMode}
onChange={(id, value) => dashboard.dispatch.setViewMode(value)}
onChange={(id, value) => dashboardApi.setViewMode(value)}
type="single"
/>
);
Expand All @@ -57,12 +54,12 @@ export const DualReduxExample = () => {
return (
<>
<EuiTitle>
<h2>Dual redux example</h2>
<h2>Dual dashboards example</h2>
</EuiTitle>
<EuiText>
<p>
Use the redux contexts from two different dashboard containers to independently set the
view mode of each dashboard.
Use the APIs from different dashboards to independently set the view mode of each
dashboard.
</p>
</EuiText>
<EuiSpacer size="m" />
Expand All @@ -73,18 +70,18 @@ export const DualReduxExample = () => {
<h3>Dashboard #1</h3>
</EuiTitle>
<EuiSpacer size="m" />
{firstDashboardContainer && <ButtonControls dashboard={firstDashboardContainer} />}
{firstDashboardApi && <ButtonControls dashboardApi={firstDashboardApi} />}
<EuiSpacer size="m" />
<DashboardRenderer ref={setFirstDashboardContainer} />
<DashboardRenderer onApiAvailable={setFirstDashboardApi} />
</EuiFlexItem>
<EuiFlexItem>
<EuiTitle size="xs">
<h3>Dashboard #2</h3>
</EuiTitle>
<EuiSpacer size="m" />
{secondDashboardContainer && <ButtonControls dashboard={secondDashboardContainer} />}
{secondDashboardApi && <ButtonControls dashboardApi={secondDashboardApi} />}
<EuiSpacer size="m" />
<DashboardRenderer ref={setSecondDashboardContainer} />
<DashboardRenderer onApiAvailable={setSecondDashboardApi} />
</EuiFlexItem>
</EuiFlexGroup>
</EuiPanel>
Expand Down

This file was deleted.

Loading

0 comments on commit 79cb9c5

Please sign in to comment.