Skip to content

Commit 27f6eb5

Browse files
committed
portal for time range selector
1 parent ebceb51 commit 27f6eb5

File tree

6 files changed

+47
-48
lines changed

6 files changed

+47
-48
lines changed

public/app/core/reducers/fn-slice.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ export type SetFnStateAction = PayloadAction<Omit<FnGlobalState, 'hiddenVariable
2323

2424
export type FnPropMappedFromState = Extract<
2525
keyof FnGlobalState,
26-
'FNDashboard' | 'hiddenVariables' | 'mode' | 'uid' | 'queryParams' | 'slug' | 'version'
26+
'FNDashboard' | 'hiddenVariables' | 'mode' | 'uid' | 'queryParams' | 'slug' | 'version' | 'controlsContainer'
2727
>;
2828
export type FnStateProp = keyof FnGlobalState;
2929

public/app/features/dashboard/containers/DashboardPage.tsx

+17-9
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { cx } from '@emotion/css';
2+
import { Portal } from '@mui/material';
23
import React, { PureComponent } from 'react';
34
import { connect, ConnectedProps, MapDispatchToProps, MapStateToProps } from 'react-redux';
45

@@ -71,7 +72,7 @@ export type MapStateToDashboardPageProps = MapStateToProps<
7172
Pick<DashboardState, 'initPhase' | 'initError'> & {
7273
dashboard: ReturnType<DashboardState['getModel']>;
7374
navIndex: StoreState['navIndex'];
74-
} & Pick<FnGlobalState, 'FNDashboard'>,
75+
} & Pick<FnGlobalState, 'FNDashboard' | 'controlsContainer'>,
7576
OwnProps,
7677
StoreState
7778
>;
@@ -92,6 +93,7 @@ export const mapStateToProps: MapStateToDashboardPageProps = (state) => ({
9293
dashboard: state.dashboard.getModel(),
9394
navIndex: state.navIndex,
9495
FNDashboard: state.fnGlobalState.FNDashboard,
96+
controlsContainer: state.fnGlobalState.controlsContainer,
9597
});
9698

9799
const mapDispatchToProps: MapDispatchToDashboardPageProps = {
@@ -376,7 +378,7 @@ export class UnthemedDashboardPage extends PureComponent<Props, State> {
376378
}
377379

378380
render() {
379-
const { dashboard, initError, queryParams, FNDashboard } = this.props;
381+
const { dashboard, initError, queryParams, FNDashboard, controlsContainer } = this.props;
380382
const { editPanel, viewPanel, updateScrollTop, pageNav, sectionNav } = this.state;
381383
const kioskMode = getKioskMode(this.props.queryParams);
382384

@@ -402,6 +404,18 @@ export class UnthemedDashboardPage extends PureComponent<Props, State> {
402404
);
403405
}
404406

407+
const FNTimeRange = !controlsContainer ? (
408+
<ToolbarButtonRow alignment="right" style={{ marginBottom: '16px' }}>
409+
<DashNavTimeControls dashboard={dashboard} onChangeTimeZone={updateTimeZoneForSession} key="time-controls" />
410+
</ToolbarButtonRow>
411+
) : (
412+
<Portal container={document.getElementById(controlsContainer)!}>
413+
<ToolbarButtonRow>
414+
<DashNavTimeControls dashboard={dashboard} onChangeTimeZone={updateTimeZoneForSession} key="time-controls" />
415+
</ToolbarButtonRow>
416+
</Portal>
417+
);
418+
405419
return (
406420
<React.Fragment>
407421
<Page
@@ -416,13 +430,7 @@ export class UnthemedDashboardPage extends PureComponent<Props, State> {
416430
{showToolbar && (
417431
<header data-testid={selectors.pages.Dashboard.DashNav.navV2}>
418432
{FNDashboard ? (
419-
<ToolbarButtonRow alignment="right" style={{ marginBottom: '16px' }}>
420-
<DashNavTimeControls
421-
dashboard={dashboard}
422-
onChangeTimeZone={updateTimeZoneForSession}
423-
key="time-controls"
424-
/>
425-
</ToolbarButtonRow>
433+
FNTimeRange
426434
) : (
427435
<DashNav
428436
dashboard={dashboard}

public/app/fn-app/create-mfe.ts

+6-10
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ declare let __webpack_public_path__: string;
44
window.__grafana_public_path__ =
55
__webpack_public_path__.substring(0, __webpack_public_path__.lastIndexOf('build/')) || __webpack_public_path__;
66

7-
import { isNull, merge, noop, omit, pick } from 'lodash';
7+
import { isNull, merge, noop, pick } from 'lodash';
88
import React, { ComponentType } from 'react';
99
import ReactDOM from 'react-dom';
1010

@@ -294,6 +294,7 @@ class createMfe {
294294
slug: other.slug,
295295
version: other.version,
296296
queryParams: other.queryParams,
297+
controlsContainer: other.controlsContainer,
297298
})
298299
);
299300
}
@@ -308,15 +309,10 @@ class createMfe {
308309
static renderMfeComponent(props: FNDashboardProps, onSuccess = noop) {
309310
const container = createMfe.getContainer(props);
310311

311-
ReactDOM.render(
312-
// @ts-ignore
313-
React.createElement(createMfe.Component, omit(props, 'hiddenVariables', 'FNDashboard')),
314-
container,
315-
() => {
316-
createMfe.logger('Created mfe component.', { props, container });
317-
onSuccess();
318-
}
319-
);
312+
ReactDOM.render(React.createElement(createMfe.Component, props), container, () => {
313+
createMfe.logger('Created mfe component.', { props, container });
314+
onSuccess();
315+
});
320316
}
321317
}
322318

Original file line numberDiff line numberDiff line change
@@ -1,14 +1,8 @@
11
import { pick } from 'lodash';
22
import React, { FC, useMemo } from 'react';
3-
import { connect, MapStateToProps } from 'react-redux';
43

5-
import {
6-
FnGlobalState,
7-
FN_STATE_KEY,
8-
FnPropMappedFromState,
9-
fnPropsMappedFromState,
10-
FnPropsMappedFromState,
11-
} from 'app/core/reducers/fn-slice';
4+
import { FnPropMappedFromState, fnPropsMappedFromState } from 'app/core/reducers/fn-slice';
5+
import { StoreState, useSelector } from 'app/types';
126

137
import { AngularRoot } from '../../angular/AngularRoot';
148
import { FnAppProvider } from '../fn-app-provider';
@@ -30,23 +24,29 @@ export const FNDashboard: FC<FNDashboardComponentProps> = (props) => {
3024
);
3125
};
3226

33-
function mapStateToProps(): MapStateToProps<
34-
FnPropsMappedFromState,
35-
Omit<FNDashboardProps, FnPropMappedFromState>,
36-
{ [K in typeof FN_STATE_KEY]: FnGlobalState }
37-
> {
38-
return ({ fnGlobalState }) => pick(fnGlobalState, ...fnPropsMappedFromState);
27+
function mapStateToProps() {
28+
return ({ fnGlobalState }: StoreState) => pick(fnGlobalState, ...fnPropsMappedFromState);
3929
}
4030

41-
export const DashboardPortalComponent: FC<FNDashboardComponentProps & FnPropsMappedFromState> = (props) => {
31+
export const DashboardPortal: FC<FNDashboardComponentProps> = (p) => {
32+
const globalFnProps = useSelector(mapStateToProps());
33+
34+
const props = useMemo(
35+
() => ({
36+
...p,
37+
...globalFnProps,
38+
}),
39+
[p, globalFnProps]
40+
);
41+
4242
const content = useMemo(() => {
4343
if (!props.FNDashboard) {
4444
return null;
4545
}
4646

47-
const { uid, slug, queryParams = {} } = props;
47+
const { uid, queryParams = {} } = props;
4848

49-
if (!uid || !slug) {
49+
if (!uid) {
5050
return null;
5151
}
5252

@@ -55,7 +55,6 @@ export const DashboardPortalComponent: FC<FNDashboardComponentProps & FnPropsMap
5555
{...{
5656
...props,
5757
uid,
58-
slug,
5958
queryParams,
6059
}}
6160
/>
@@ -64,5 +63,3 @@ export const DashboardPortalComponent: FC<FNDashboardComponentProps & FnPropsMap
6463

6564
return <RenderPortal ID="grafana-portal">{content}</RenderPortal>;
6665
};
67-
68-
export const DashboardPortal = connect(mapStateToProps())(DashboardPortalComponent);

public/app/fn-app/types.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ export interface FNDashboardProps {
2727
queryParams: ParsedQuery<string>;
2828
fnError?: ReactNode;
2929
pageTitle?: string;
30-
controlsContainer: string;
30+
controlsContainer: string | null;
3131
isLoading: (isLoading: boolean) => void;
3232
setErrors: (errors?: { [K: number | string]: string }) => void;
3333
hiddenVariables: readonly string[];

public/app/fn-app/utils.tsx

+5-7
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,16 @@
1-
import { FC, PropsWithChildren } from 'react';
2-
import ReactDOM from 'react-dom';
1+
import { Portal } from '@mui/material';
2+
import React, { FC, PropsWithChildren } from 'react';
33

44
export interface RenderPortalProps {
55
ID: string;
66
}
77

8-
export const getPortalContainer = (ID: string): HTMLElement | null => document.getElementById(ID);
9-
108
export const RenderPortal: FC<PropsWithChildren<RenderPortalProps>> = ({ ID, children }) => {
11-
const portalDiv = getPortalContainer(ID);
9+
const container = document.getElementById(ID);
1210

13-
if (!portalDiv) {
11+
if (!container) {
1412
return null;
1513
}
1614

17-
return ReactDOM.createPortal(children, portalDiv);
15+
return <Portal container={container}>{children}</Portal>;
1816
};

0 commit comments

Comments
 (0)