Navigation: Initialise navTree in redux store (#44440)

* Add navTree to redux store and used that in NavBar/NavBarNext

* Use createSlice

* update import

* Use NavBarUnconnected instead of Component
This commit is contained in:
Ashley Harrison 2022-01-28 10:06:52 +00:00 committed by GitHub
parent 6de9d241a6
commit 666a794a82
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 51 additions and 9 deletions

View File

@ -1,4 +1,5 @@
import React, { useState } from 'react'; import React, { useState } from 'react';
import { connect, ConnectedProps } from 'react-redux';
import { useLocation } from 'react-router-dom'; import { useLocation } from 'react-router-dom';
import { css, cx } from '@emotion/css'; import { css, cx } from '@emotion/css';
import { cloneDeep } from 'lodash'; import { cloneDeep } from 'lodash';
@ -7,7 +8,7 @@ import { Icon, IconName, useTheme2 } from '@grafana/ui';
import { locationService } from '@grafana/runtime'; import { locationService } from '@grafana/runtime';
import { Branding } from 'app/core/components/Branding/Branding'; import { Branding } from 'app/core/components/Branding/Branding';
import config from 'app/core/config'; import config from 'app/core/config';
import { KioskMode } from 'app/types'; import { StoreState, KioskMode } from 'app/types';
import { enrichConfigItems, getActiveItem, isMatchOrChildMatch, isSearchActive, SEARCH_ITEM_ID } from './utils'; import { enrichConfigItems, getActiveItem, isMatchOrChildMatch, isSearchActive, SEARCH_ITEM_ID } from './utils';
import { OrgSwitcher } from '../OrgSwitcher'; import { OrgSwitcher } from '../OrgSwitcher';
import NavBarItem from './NavBarItem'; import NavBarItem from './NavBarItem';
@ -28,7 +29,17 @@ const searchItem: NavModelItem = {
icon: 'search', icon: 'search',
}; };
export const NavBar = React.memo(() => { const mapStateToProps = (state: StoreState) => ({
navBarTree: state.navBarTree,
});
const mapDispatchToProps = {};
const connector = connect(mapStateToProps, mapDispatchToProps);
export interface Props extends ConnectedProps<typeof connector> {}
export const NavBarUnconnected = React.memo(({ navBarTree }: Props) => {
const theme = useTheme2(); const theme = useTheme2();
const styles = getStyles(theme); const styles = getStyles(theme);
const location = useLocation(); const location = useLocation();
@ -38,7 +49,7 @@ export const NavBar = React.memo(() => {
const toggleSwitcherModal = () => { const toggleSwitcherModal = () => {
setShowSwitcherModal(!showSwitcherModal); setShowSwitcherModal(!showSwitcherModal);
}; };
const navTree: NavModelItem[] = cloneDeep(config.bootData.navTree); const navTree = cloneDeep(navBarTree);
const topItems = navTree.filter((item) => item.section === NavSection.Core); const topItems = navTree.filter((item) => item.section === NavSection.Core);
const bottomItems = enrichConfigItems( const bottomItems = enrichConfigItems(
navTree.filter((item) => item.section === NavSection.Config), navTree.filter((item) => item.section === NavSection.Config),
@ -109,7 +120,9 @@ export const NavBar = React.memo(() => {
); );
}); });
NavBar.displayName = 'NavBar'; NavBarUnconnected.displayName = 'NavBar';
export const NavBar = connector(NavBarUnconnected);
const getStyles = (theme: GrafanaTheme2) => ({ const getStyles = (theme: GrafanaTheme2) => ({
search: css` search: css`

View File

@ -5,8 +5,7 @@ import { cloneDeep } from 'lodash';
import { GrafanaTheme2, NavModelItem, NavSection } from '@grafana/data'; import { GrafanaTheme2, NavModelItem, NavSection } from '@grafana/data';
import { Icon, IconName, useTheme2 } from '@grafana/ui'; import { Icon, IconName, useTheme2 } from '@grafana/ui';
import { locationService } from '@grafana/runtime'; import { locationService } from '@grafana/runtime';
import config from 'app/core/config'; import { KioskMode, StoreState } from 'app/types';
import { KioskMode } from 'app/types';
import { enrichConfigItems, getActiveItem, isMatchOrChildMatch, isSearchActive, SEARCH_ITEM_ID } from './utils'; import { enrichConfigItems, getActiveItem, isMatchOrChildMatch, isSearchActive, SEARCH_ITEM_ID } from './utils';
import { OrgSwitcher } from '../OrgSwitcher'; import { OrgSwitcher } from '../OrgSwitcher';
import { NavBarSection } from './NavBarSection'; import { NavBarSection } from './NavBarSection';
@ -14,6 +13,7 @@ import { NavBarMenu } from './NavBarMenu';
import NavBarItem from './NavBarItem'; import NavBarItem from './NavBarItem';
import { NavBarItemWithoutMenu } from './NavBarItemWithoutMenu'; import { NavBarItemWithoutMenu } from './NavBarItemWithoutMenu';
import { Branding } from '../Branding/Branding'; import { Branding } from '../Branding/Branding';
import { connect, ConnectedProps } from 'react-redux';
const onOpenSearch = () => { const onOpenSearch = () => {
locationService.partial({ search: 'open' }); locationService.partial({ search: 'open' });
@ -26,7 +26,17 @@ const searchItem: NavModelItem = {
icon: 'search', icon: 'search',
}; };
export const NavBarNext = React.memo(() => { const mapStateToProps = (state: StoreState) => ({
navBarTree: state.navBarTree,
});
const mapDispatchToProps = {};
const connector = connect(mapStateToProps, mapDispatchToProps);
export interface Props extends ConnectedProps<typeof connector> {}
export const NavBarNextUnconnected = React.memo(({ navBarTree }: Props) => {
const theme = useTheme2(); const theme = useTheme2();
const styles = getStyles(theme); const styles = getStyles(theme);
const location = useLocation(); const location = useLocation();
@ -36,7 +46,7 @@ export const NavBarNext = React.memo(() => {
const toggleSwitcherModal = () => { const toggleSwitcherModal = () => {
setShowSwitcherModal(!showSwitcherModal); setShowSwitcherModal(!showSwitcherModal);
}; };
const navTree: NavModelItem[] = cloneDeep(config.bootData.navTree); const navTree = cloneDeep(navBarTree);
const coreItems = navTree.filter((item) => item.section === NavSection.Core); const coreItems = navTree.filter((item) => item.section === NavSection.Core);
const pluginItems = navTree.filter((item) => item.section === NavSection.Plugin); const pluginItems = navTree.filter((item) => item.section === NavSection.Plugin);
const configItems = enrichConfigItems( const configItems = enrichConfigItems(
@ -118,7 +128,9 @@ export const NavBarNext = React.memo(() => {
); );
}); });
NavBarNext.displayName = 'NavBar'; NavBarNextUnconnected.displayName = 'NavBarNext';
export const NavBarNext = connector(NavBarNextUnconnected);
const getStyles = (theme: GrafanaTheme2) => ({ const getStyles = (theme: GrafanaTheme2) => ({
search: css` search: css`

View File

@ -1,7 +1,9 @@
import { navIndexReducer as navIndex } from './navModel'; import { navIndexReducer as navIndex } from './navModel';
import { navTreeReducer as navBarTree } from './navBarTree';
import { appNotificationsReducer as appNotifications } from './appNotification'; import { appNotificationsReducer as appNotifications } from './appNotification';
export default { export default {
navBarTree,
navIndex, navIndex,
appNotifications, appNotifications,
}; };

View File

@ -0,0 +1,15 @@
import { createSlice } from '@reduxjs/toolkit';
import { NavModelItem } from '@grafana/data';
import config from 'app/core/config';
export const initialState: NavModelItem[] = config.bootData.navTree;
const navTreeSlice = createSlice({
name: 'navBarTree',
initialState,
reducers: {},
});
export const {} = navTreeSlice.actions;
export const navTreeReducer = navTreeSlice.reducer;