mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Navbar: remove visual sections + home button (#46693)
* Navbar: remove visual sections + home button * remove padding * Fix label
This commit is contained in:
parent
6c468daabc
commit
7d8af12cca
@ -38,7 +38,6 @@ const (
|
|||||||
// any items with default weight.
|
// any items with default weight.
|
||||||
|
|
||||||
WeightSavedItems = (iota - 20) * 100
|
WeightSavedItems = (iota - 20) * 100
|
||||||
WeightHome
|
|
||||||
WeightCreate
|
WeightCreate
|
||||||
WeightDashboard
|
WeightDashboard
|
||||||
WeightExplore
|
WeightExplore
|
||||||
|
@ -172,15 +172,6 @@ func (hs *HTTPServer) getNavTree(c *models.ReqContext, hasEditPerm bool) ([]*dto
|
|||||||
Section: dtos.NavSectionCore,
|
Section: dtos.NavSectionCore,
|
||||||
Children: savedItemsLinks,
|
Children: savedItemsLinks,
|
||||||
})
|
})
|
||||||
|
|
||||||
navTree = append(navTree, &dtos.NavLink{
|
|
||||||
Text: "Home",
|
|
||||||
Id: "home",
|
|
||||||
Icon: "home-alt",
|
|
||||||
Url: hs.Cfg.AppSubURL + "/",
|
|
||||||
Section: dtos.NavSectionCore,
|
|
||||||
SortWeight: dtos.WeightHome,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if hasEditPerm && !hs.Features.IsEnabled(featuremgmt.FlagNewNavigation) {
|
if hasEditPerm && !hs.Features.IsEnabled(featuremgmt.FlagNewNavigation) {
|
||||||
|
@ -6,6 +6,7 @@ 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 { getKioskMode } from 'app/core/navigation/kiosk';
|
import { getKioskMode } from 'app/core/navigation/kiosk';
|
||||||
|
import config from 'app/core/config';
|
||||||
import { KioskMode, StoreState } from 'app/types';
|
import { KioskMode, StoreState } 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';
|
||||||
@ -29,7 +30,7 @@ const searchItem: NavModelItem = {
|
|||||||
|
|
||||||
export const NavBarNext = React.memo(() => {
|
export const NavBarNext = React.memo(() => {
|
||||||
const navBarTree = useSelector((state: StoreState) => state.navBarTree);
|
const navBarTree = useSelector((state: StoreState) => state.navBarTree);
|
||||||
|
const homeUrl = config.appSubUrl || '/';
|
||||||
const theme = useTheme2();
|
const theme = useTheme2();
|
||||||
const styles = getStyles(theme);
|
const styles = getStyles(theme);
|
||||||
const location = useLocation();
|
const location = useLocation();
|
||||||
@ -39,16 +40,21 @@ export const NavBarNext = React.memo(() => {
|
|||||||
setShowSwitcherModal(!showSwitcherModal);
|
setShowSwitcherModal(!showSwitcherModal);
|
||||||
};
|
};
|
||||||
const navTree = cloneDeep(navBarTree);
|
const navTree = cloneDeep(navBarTree);
|
||||||
|
|
||||||
|
// Here we need to hack in a "home" NavModelItem since this is constructed in the frontend
|
||||||
|
const homeLink: NavModelItem = {
|
||||||
|
text: 'Home',
|
||||||
|
url: config.appSubUrl || '/',
|
||||||
|
};
|
||||||
|
navTree.unshift(homeLink);
|
||||||
|
|
||||||
const coreItems = navTree.filter((item) => item.section === NavSection.Core);
|
const coreItems = navTree.filter((item) => item.section === NavSection.Core);
|
||||||
const pinnedCoreItems = coreItems.filter((item) => !item.hideFromNavbar);
|
|
||||||
const pluginItems = navTree.filter((item) => item.section === NavSection.Plugin);
|
const pluginItems = navTree.filter((item) => item.section === NavSection.Plugin);
|
||||||
const pinnedPluginItems = pluginItems.filter((item) => !item.hideFromNavbar);
|
|
||||||
const configItems = enrichConfigItems(
|
const configItems = enrichConfigItems(
|
||||||
navTree.filter((item) => item.section === NavSection.Config),
|
navTree.filter((item) => item.section === NavSection.Config),
|
||||||
location,
|
location,
|
||||||
toggleSwitcherModal
|
toggleSwitcherModal
|
||||||
);
|
);
|
||||||
const pinnedConfigItems = configItems.filter((item) => !item.hideFromNavbar);
|
|
||||||
const activeItem = isSearchActive(location) ? searchItem : getActiveItem(navTree, location.pathname);
|
const activeItem = isSearchActive(location) ? searchItem : getActiveItem(navTree, location.pathname);
|
||||||
const [menuOpen, setMenuOpen] = useState(false);
|
const [menuOpen, setMenuOpen] = useState(false);
|
||||||
|
|
||||||
@ -63,7 +69,12 @@ export const NavBarNext = React.memo(() => {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<NavBarSection>
|
<NavBarSection>
|
||||||
<NavBarItemWithoutMenu label="Main menu" className={styles.grafanaLogo} onClick={() => setMenuOpen(!menuOpen)}>
|
<NavBarItemWithoutMenu
|
||||||
|
isActive={isMatchOrChildMatch(homeLink, activeItem)}
|
||||||
|
label="Home"
|
||||||
|
className={styles.grafanaLogo}
|
||||||
|
url={homeUrl}
|
||||||
|
>
|
||||||
<Branding.MenuLogo />
|
<Branding.MenuLogo />
|
||||||
</NavBarItemWithoutMenu>
|
</NavBarItemWithoutMenu>
|
||||||
<NavBarItem className={styles.search} isActive={activeItem === searchItem} link={searchItem}>
|
<NavBarItem className={styles.search} isActive={activeItem === searchItem} link={searchItem}>
|
||||||
@ -72,7 +83,7 @@ export const NavBarNext = React.memo(() => {
|
|||||||
</NavBarSection>
|
</NavBarSection>
|
||||||
|
|
||||||
<NavBarSection>
|
<NavBarSection>
|
||||||
{pinnedCoreItems.map((link, index) => (
|
{coreItems.map((link, index) => (
|
||||||
<NavBarItem
|
<NavBarItem
|
||||||
key={`${link.id}-${index}`}
|
key={`${link.id}-${index}`}
|
||||||
isActive={isMatchOrChildMatch(link, activeItem)}
|
isActive={isMatchOrChildMatch(link, activeItem)}
|
||||||
@ -84,21 +95,19 @@ export const NavBarNext = React.memo(() => {
|
|||||||
))}
|
))}
|
||||||
</NavBarSection>
|
</NavBarSection>
|
||||||
|
|
||||||
{pinnedPluginItems.length > 0 && (
|
|
||||||
<NavBarSection>
|
<NavBarSection>
|
||||||
{pinnedPluginItems.map((link, index) => (
|
{pluginItems.map((link, index) => (
|
||||||
<NavBarItem key={`${link.id}-${index}`} isActive={isMatchOrChildMatch(link, activeItem)} link={link}>
|
<NavBarItem key={`${link.id}-${index}`} isActive={isMatchOrChildMatch(link, activeItem)} link={link}>
|
||||||
{link.icon && <Icon name={link.icon as IconName} size="xl" />}
|
{link.icon && <Icon name={link.icon as IconName} size="xl" />}
|
||||||
{link.img && <img src={link.img} alt={`${link.text} logo`} />}
|
{link.img && <img src={link.img} alt={`${link.text} logo`} />}
|
||||||
</NavBarItem>
|
</NavBarItem>
|
||||||
))}
|
))}
|
||||||
</NavBarSection>
|
</NavBarSection>
|
||||||
)}
|
|
||||||
|
|
||||||
<div className={styles.spacer} />
|
<div className={styles.spacer} />
|
||||||
|
|
||||||
<NavBarSection>
|
<NavBarSection>
|
||||||
{pinnedConfigItems.map((link, index) => (
|
{configItems.map((link, index) => (
|
||||||
<NavBarItem
|
<NavBarItem
|
||||||
key={`${link.id}-${index}`}
|
key={`${link.id}-${index}`}
|
||||||
isActive={isMatchOrChildMatch(link, activeItem)}
|
isActive={isMatchOrChildMatch(link, activeItem)}
|
||||||
@ -141,9 +150,8 @@ const getStyles = (theme: GrafanaTheme2) => ({
|
|||||||
z-index: ${theme.zIndex.sidemenu};
|
z-index: ${theme.zIndex.sidemenu};
|
||||||
|
|
||||||
${theme.breakpoints.up('md')} {
|
${theme.breakpoints.up('md')} {
|
||||||
gap: ${theme.spacing(1)};
|
background: ${theme.colors.background.primary};
|
||||||
margin-left: ${theme.spacing(1)};
|
border-right: 1px solid ${theme.components.panel.borderColor};
|
||||||
padding: ${theme.spacing(1)} 0;
|
|
||||||
position: relative;
|
position: relative;
|
||||||
width: ${theme.components.sidemenu.width}px;
|
width: ${theme.components.sidemenu.width}px;
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,6 @@ import React, { ReactNode } from 'react';
|
|||||||
import { css, cx } from '@emotion/css';
|
import { css, cx } from '@emotion/css';
|
||||||
import { GrafanaTheme2 } from '@grafana/data';
|
import { GrafanaTheme2 } from '@grafana/data';
|
||||||
import { useTheme2 } from '@grafana/ui';
|
import { useTheme2 } from '@grafana/ui';
|
||||||
import { config } from '@grafana/runtime';
|
|
||||||
|
|
||||||
export interface Props {
|
export interface Props {
|
||||||
children: ReactNode;
|
children: ReactNode;
|
||||||
@ -10,9 +9,8 @@ export interface Props {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function NavBarSection({ children, className }: Props) {
|
export function NavBarSection({ children, className }: Props) {
|
||||||
const newNavigationEnabled = Boolean(config.featureToggles.newNavigation);
|
|
||||||
const theme = useTheme2();
|
const theme = useTheme2();
|
||||||
const styles = getStyles(theme, newNavigationEnabled);
|
const styles = getStyles(theme);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ul data-testid="navbar-section" className={cx(styles.container, className)}>
|
<ul data-testid="navbar-section" className={cx(styles.container, className)}>
|
||||||
@ -21,15 +19,12 @@ export function NavBarSection({ children, className }: Props) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const getStyles = (theme: GrafanaTheme2, newNavigationEnabled: boolean) => ({
|
const getStyles = (theme: GrafanaTheme2) => ({
|
||||||
container: css`
|
container: css`
|
||||||
display: none;
|
display: none;
|
||||||
list-style: none;
|
list-style: none;
|
||||||
|
|
||||||
${theme.breakpoints.up('md')} {
|
${theme.breakpoints.up('md')} {
|
||||||
background-color: ${newNavigationEnabled ? theme.colors.background.primary : 'inherit'};
|
|
||||||
border: ${newNavigationEnabled ? `1px solid ${theme.components.panel.borderColor}` : 'none'};
|
|
||||||
border-radius: 2px;
|
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: inherit;
|
flex-direction: inherit;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user