Skip to content

Commit 867df86

Browse files
ziomeckaKatarzyna Ziomek-Zdanowicz
authored andcommitted
7829 Read hiddenVariables, mode, FNDashboard from grfana's state (#44)
Co-authored-by: Katarzyna Ziomek-Zdanowicz <[email protected]>
1 parent 82e642b commit 867df86

File tree

8 files changed

+205
-170
lines changed

8 files changed

+205
-170
lines changed

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

+48-38
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
1-
import { createSlice, PayloadAction } from '@reduxjs/toolkit';
2-
import { WritableDraft } from 'immer/dist/internal';
1+
import { createSlice, PayloadAction, SliceCaseReducers } from '@reduxjs/toolkit';
32

43
import { GrafanaThemeType } from '@grafana/data';
5-
import { dispatch } from 'app/store/store';
64

75
import { AnyObject } from '../../fn-app/types';
86

@@ -14,17 +12,41 @@ export interface FnGlobalState {
1412
controlsContainer: string | null;
1513
pageTitle: string;
1614
queryParams: AnyObject;
17-
hiddenVariables: string[];
15+
hiddenVariables: readonly string[];
1816
}
1917

20-
export type UpdateFNGlobalStateAction = PayloadAction<{
21-
type: keyof FnGlobalState;
22-
payload: FnGlobalState[keyof FnGlobalState];
23-
}>;
18+
export type UpdateFNGlobalStateAction = PayloadAction<Partial<FnGlobalState>>;
19+
20+
export type SetFnStateAction = PayloadAction<Omit<FnGlobalState, 'hiddenVariables'>>;
21+
22+
export type FnPropMappedFromState = Extract<keyof FnGlobalState, 'FNDashboard' | 'hiddenVariables' | 'mode'>;
23+
export type FnStateProp = keyof FnGlobalState;
24+
25+
export type FnPropsMappedFromState = Pick<FnGlobalState, FnPropMappedFromState>;
26+
27+
export const fnStateProps: FnStateProp[] = [
28+
'FNDashboard',
29+
'controlsContainer',
30+
'hiddenVariables',
31+
'mode',
32+
'pageTitle',
33+
'queryParams',
34+
'slug',
35+
'uid',
36+
];
37+
38+
export const fnPropsMappedFromState: readonly FnPropMappedFromState[] = [
39+
'FNDashboard',
40+
'hiddenVariables',
41+
'mode',
42+
] as const;
2443

2544
const INITIAL_MODE = GrafanaThemeType.Light;
2645

27-
const initialState: FnGlobalState = {
46+
export const FN_STATE_KEY = 'fnGlobalState';
47+
48+
export const INITIAL_FN_STATE: FnGlobalState = {
49+
// NOTE: initial value is false
2850
FNDashboard: false,
2951
uid: '',
3052
slug: '',
@@ -33,37 +55,25 @@ const initialState: FnGlobalState = {
3355
pageTitle: '',
3456
queryParams: {},
3557
hiddenVariables: [],
36-
};
58+
} as const;
3759

38-
const fnSlice = createSlice({
39-
name: 'fnGlobalState',
40-
initialState,
41-
reducers: {
42-
setInitialMountState: (state, action: PayloadAction<Omit<FnGlobalState, 'hiddenVariables'>>) => {
43-
return { ...state, ...action.payload };
44-
},
45-
updateFnState: (state: WritableDraft<FnGlobalState>, action: UpdateFNGlobalStateAction) => {
46-
const { type, payload } = action.payload;
47-
48-
return {
49-
...state,
50-
[type]: payload,
51-
};
52-
},
60+
const reducers: SliceCaseReducers<FnGlobalState> = {
61+
updateFnState: (state, action: SetFnStateAction) => {
62+
return { ...state, ...action.payload };
63+
},
64+
updatePartialFnStates: (state, action: UpdateFNGlobalStateAction) => {
65+
return {
66+
...state,
67+
...action.payload,
68+
};
5369
},
70+
};
71+
72+
const fnSlice = createSlice<FnGlobalState, SliceCaseReducers<FnGlobalState>, string>({
73+
name: FN_STATE_KEY,
74+
initialState: INITIAL_FN_STATE,
75+
reducers,
5476
});
5577

56-
export const { updateFnState, setInitialMountState } = fnSlice.actions;
78+
export const { updatePartialFnStates, updateFnState } = fnSlice.actions;
5779
export const fnSliceReducer = fnSlice.reducer;
58-
59-
export const updateFNGlobalState = (
60-
type: keyof FnGlobalState,
61-
payload: UpdateFNGlobalStateAction['payload']['payload']
62-
): void => {
63-
dispatch(
64-
updateFnState({
65-
type,
66-
payload,
67-
})
68-
);
69-
};

public/app/features/dashboard/components/SubMenu/SubMenu.tsx

+7-3
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,7 @@ import * as React from 'react';
44
import { connect, MapStateToProps } from 'react-redux';
55

66
import { AnnotationQuery, DataQuery, TypedVariableModel, GrafanaTheme2 } from '@grafana/data';
7-
import { DashboardLink } from '@grafana/schema';
8-
import { stylesFactory, Themeable2, withTheme2 } from '@grafana/ui';
7+
import { FnGlobalState } from 'app/core/reducers/fn-slice';
98

109
import { StoreState } from '../../../../types';
1110
import { getSubMenuVariables, getVariablesState } from '../../../variables/state/selectors';
@@ -14,16 +13,19 @@ import { DashboardModel } from '../../state';
1413
import { Annotations } from './Annotations';
1514
import { DashboardLinks } from './DashboardLinks';
1615
import { SubMenuItems } from './SubMenuItems';
16+
import { VariableModel } from 'app/features/variables/types';
17+
import { Themeable2, stylesFactory, withTheme2 } from '@grafana-ui';
18+
import { DashboardLink } from '@grafana/schema/dist/esm/index';
1719

1820
interface OwnProps extends Themeable2 {
1921
dashboard: DashboardModel;
2022
links: DashboardLink[];
2123
annotations: AnnotationQuery[];
22-
hiddenVariables?: string[];
2324
}
2425

2526
interface ConnectedProps {
2627
variables: TypedVariableModel[];
28+
hiddenVariables: FnGlobalState['hiddenVariables'];
2729
}
2830

2931
interface DispatchProps {}
@@ -79,8 +81,10 @@ class SubMenuUnConnected extends PureComponent<Props> {
7981
const mapStateToProps: MapStateToProps<ConnectedProps, OwnProps, StoreState> = (state, ownProps) => {
8082
const { uid } = ownProps.dashboard;
8183
const templatingState = getVariablesState(uid, state);
84+
8285
return {
8386
variables: getSubMenuVariables(uid, templatingState.variables),
87+
hiddenVariables: state.fnGlobalState.hiddenVariables,
8488
};
8589
};
8690

public/app/features/dashboard/components/SubMenu/SubMenuItems.tsx

+4-2
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,19 @@ import { useEffect, useState, FC } from 'react';
44
import { GrafanaTheme2, TypedVariableModel, VariableHide } from '@grafana/data';
55
import { selectors } from '@grafana/e2e-selectors';
66
import { useStyles2 } from '@grafana/ui';
7+
import { FnGlobalState } from 'app/core/reducers/fn-slice';
78

89
import { PickerRenderer } from '../../../variables/pickers/PickerRenderer';
910

1011
interface Props {
1112
variables: TypedVariableModel[];
1213
readOnly?: boolean;
13-
hiddenVariables?: string[];
14+
hiddenVariables?: FnGlobalState['hiddenVariables'];
1415
}
1516

1617
export const SubMenuItems: FC<Props> = ({ variables, readOnly, hiddenVariables }) => {
1718
const [visibleVariables, setVisibleVariables] = useState<TypedVariableModel[]>([]);
19+
const styles = useStyles2(getStyles);
1820

1921
useEffect(() => {
2022
setVisibleVariables(variables.filter((state) => state.hide !== VariableHide.hideVariable));
@@ -34,7 +36,7 @@ export const SubMenuItems: FC<Props> = ({ variables, readOnly, hiddenVariables }
3436
return (
3537
<div
3638
key={variable.id}
37-
className="submenu-item gf-form-inline"
39+
className={styles.submenuItem}
3840
data-testid={selectors.pages.Dashboard.SubMenu.submenuItem}
3941
>
4042
<PickerRenderer variable={variable} readOnly={readOnly} />

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

+23-23
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import { createErrorNotification } from 'app/core/copy/appNotification';
1515
import { getKioskMode } from 'app/core/navigation/kiosk';
1616
import { GrafanaRouteComponentProps } from 'app/core/navigation/types';
1717
import { ID_PREFIX } from 'app/core/reducers/navBarTree';
18+
import { FnGlobalState } from 'app/core/reducers/fn-slice';
1819
import { getNavModel } from 'app/core/selectors/navModel';
1920
import { PanelModel } from 'app/features/dashboard/state';
2021
import { dashboardWatcher } from 'app/features/live/dashboard/dashboardWatcher';
@@ -50,7 +51,10 @@ import 'react-grid-layout/css/styles.css';
5051
import 'react-resizable/css/styles.css';
5152

5253
export type MapStateToDashboardPageProps = MapStateToProps<
53-
Pick<DashboardState, 'initPhase' | 'initError'> & { dashboard: ReturnType<DashboardState['getModel']> },
54+
Pick<DashboardState, 'initPhase' | 'initError'> & { dashboard: ReturnType<DashboardState['getModel']> } & Pick<
55+
FnGlobalState,
56+
'FNDashboard'
57+
>,
5458
OwnProps,
5559
StoreState
5660
>;
@@ -70,6 +74,7 @@ export const mapStateToProps: MapStateToDashboardPageProps = (state) => ({
7074
initError: state.dashboard.initError,
7175
dashboard: state.dashboard.getModel(),
7276
navIndex: state.navIndex,
77+
FNDashboard: state.fnGlobalState.FNDashboard,
7378
});
7479

7580
const mapDispatchToProps: MapDispatchToDashboardPageProps = {
@@ -84,9 +89,7 @@ const connector = connect(mapStateToProps, mapDispatchToProps);
8489

8590
type OwnProps = {
8691
isPublic?: boolean;
87-
isFNDashboard?: boolean;
8892
controlsContainer?: string | null;
89-
hiddenVariables?: string[];
9093
fnLoader?: ReactNode;
9194
};
9295

@@ -167,9 +170,11 @@ export class UnthemedDashboardPage extends PureComponent<Props, State> {
167170

168171
componentDidMount() {
169172
this.initDashboard();
170-
const { isPublic, isFNDashboard } = this.props;
171-
if (!isPublic && !isFNDashboard) {
172-
this.forceRouteReloadCounter = (this.props.history.location.state as any)?.routeReloadCounter || 0;
173+
174+
const { isPublic, FNDashboard } = this.props;
175+
176+
if (!isPublic && !FNDashboard) {
177+
this.forceRouteReloadCounter = (this.props.history.location?.state as any)?.routeReloadCounter || 0;
173178
}
174179
}
175180

@@ -183,7 +188,7 @@ export class UnthemedDashboardPage extends PureComponent<Props, State> {
183188
}
184189

185190
initDashboard() {
186-
const { dashboard, isPublic, match, queryParams, isFNDashboard } = this.props;
191+
const { dashboard, isPublic, match, queryParams, FNDashboard } = this.props;
187192

188193
if (dashboard) {
189194
this.closeDashboard();
@@ -196,7 +201,7 @@ export class UnthemedDashboardPage extends PureComponent<Props, State> {
196201
urlFolderUid: queryParams.folderUid,
197202
panelType: queryParams.panelType,
198203
routeName: this.props.route.routeName,
199-
fixUrl: !isPublic && !isFNDashboard,
204+
fixUrl: !isPublic && !FNDashboard,
200205
accessToken: match.params.accessToken,
201206
keybindingSrv: this.context.keybindings,
202207
});
@@ -206,13 +211,13 @@ export class UnthemedDashboardPage extends PureComponent<Props, State> {
206211
}
207212

208213
componentDidUpdate(prevProps: Props, prevState: State) {
209-
const { dashboard, match, templateVarsChangedInUrl, isPublic, isFNDashboard } = this.props;
214+
const { dashboard, match, templateVarsChangedInUrl, isPublic, FNDashboard } = this.props;
210215

211216
if (!dashboard) {
212217
return;
213218
}
214219

215-
if (!isPublic && !isFNDashboard) {
220+
if (!isPublic && !FNDashboard) {
216221
const routeReloadCounter = (this.props.history.location?.state as any)?.routeReloadCounter;
217222

218223
if (
@@ -391,11 +396,11 @@ export class UnthemedDashboardPage extends PureComponent<Props, State> {
391396
};
392397

393398
render() {
394-
const { dashboard, initError, queryParams, isPublic, isFNDashboard, fnLoader } = this.props;
399+
const { dashboard, initError, queryParams, isPublic, FNDashboard, fnLoader } = this.props;
395400
const { editPanel, viewPanel, updateScrollTop, pageNav, sectionNav } = this.state;
396-
const kioskMode = isFNDashboard ? KioskMode.FN : !isPublic ? getKioskMode(this.props.queryParams) : KioskMode.Full;
401+
const kioskMode = FNDashboard ? KioskMode.FN : !isPublic ? getKioskMode(this.props.queryParams) : KioskMode.Full;
397402

398-
if (!dashboard ) {
403+
if (!dashboard) {
399404
return fnLoader ? <>{fnLoader}</> : <DashboardLoading initPhase={this.props.initPhase} />;
400405
}
401406

@@ -406,7 +411,7 @@ export class UnthemedDashboardPage extends PureComponent<Props, State> {
406411
<header data-testid={selectors.pages.Dashboard.DashNav.navV2}>
407412
<DashNav
408413
dashboard={dashboard}
409-
title={!isFNDashboard ? dashboard.title : ''}
414+
title={!FNDashboard ? dashboard.title : ''}
410415
folderTitle={dashboard.meta.folderTitle}
411416
isFullscreen={!!viewPanel}
412417
onAddPanel={this.onAddPanel}
@@ -490,17 +495,12 @@ export class UnthemedDashboardPage extends PureComponent<Props, State> {
490495
className={pageClassName}
491496
onSetScrollRef={this.setScrollRef}
492497
>
493-
{!isFNDashboard && <DashboardPrompt dashboard={dashboard} />}
498+
{!FNDashboard && <DashboardPrompt dashboard={dashboard} />}
494499

495500
{initError && <DashboardFailed />}
496501
{showSubMenu && (
497502
<section aria-label={selectors.pages.Dashboard.SubMenu.submenu}>
498-
<SubMenu
499-
dashboard={dashboard}
500-
annotations={dashboard.annotations.list}
501-
links={dashboard.links}
502-
hiddenVariables={this.props.hiddenVariables}
503-
/>
503+
<SubMenu dashboard={dashboard} annotations={dashboard.annotations.list} links={dashboard.links} />
504504
</section>
505505
)}
506506
{config.featureToggles.angularDeprecationUI && dashboard.hasAngularPlugins() && dashboard.uid !== null && (
@@ -548,9 +548,9 @@ export class UnthemedDashboardPage extends PureComponent<Props, State> {
548548
}
549549

550550
function updateStatePageNavFromProps(props: Props, state: State): State {
551-
const { dashboard, isFNDashboard } = props;
551+
const { dashboard, FNDashboard } = props;
552552

553-
if (!dashboard || isFNDashboard) {
553+
if (!dashboard || FNDashboard) {
554554
return state;
555555
}
556556

0 commit comments

Comments
 (0)