mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
TopNav: Adding sign in to topnav and hiding it mega menu (#56403)
* TopNav: Adding sign in to topnav and hiding it mega menu * Added target _self * remove scss change * Fix sign in link * Fix other link
This commit is contained in:
parent
0958d9ba55
commit
a8b883b1fa
29
public/app/core/components/AppChrome/TopBar/SignInLink.tsx
Normal file
29
public/app/core/components/AppChrome/TopBar/SignInLink.tsx
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
import { css } from '@emotion/css';
|
||||||
|
import React from 'react';
|
||||||
|
import { useLocation } from 'react-router-dom';
|
||||||
|
|
||||||
|
import { locationUtil } from '@grafana/data';
|
||||||
|
import { useStyles2 } from '@grafana/ui';
|
||||||
|
|
||||||
|
export function SignInLink() {
|
||||||
|
const location = useLocation();
|
||||||
|
const styles = useStyles2(getStyles);
|
||||||
|
const loginUrl = locationUtil.getUrlForPartial(location, { forceLogin: 'true' });
|
||||||
|
|
||||||
|
return (
|
||||||
|
<a className={styles.link} href={loginUrl} target="_self">
|
||||||
|
Sign in
|
||||||
|
</a>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const getStyles = () => {
|
||||||
|
return {
|
||||||
|
link: css({
|
||||||
|
whiteSpace: 'nowrap',
|
||||||
|
'&:hover': {
|
||||||
|
textDecoration: 'underline',
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
};
|
||||||
|
};
|
@ -7,6 +7,7 @@ import { contextSrv } from 'app/core/core';
|
|||||||
import { useSelector } from 'app/types';
|
import { useSelector } from 'app/types';
|
||||||
|
|
||||||
import { NewsContainer } from './News/NewsContainer';
|
import { NewsContainer } from './News/NewsContainer';
|
||||||
|
import { SignInLink } from './TopBar/SignInLink';
|
||||||
import { TopNavBarMenu } from './TopBar/TopNavBarMenu';
|
import { TopNavBarMenu } from './TopBar/TopNavBarMenu';
|
||||||
import { TopSearchBarInput } from './TopSearchBarInput';
|
import { TopSearchBarInput } from './TopSearchBarInput';
|
||||||
import { TOP_BAR_LEVEL_HEIGHT } from './types';
|
import { TOP_BAR_LEVEL_HEIGHT } from './types';
|
||||||
@ -35,6 +36,7 @@ export function TopSearchBar() {
|
|||||||
</Dropdown>
|
</Dropdown>
|
||||||
)}
|
)}
|
||||||
<NewsContainer />
|
<NewsContainer />
|
||||||
|
{!contextSrv.user.isSignedIn && <SignInLink />}
|
||||||
{profileNode && (
|
{profileNode && (
|
||||||
<Dropdown overlay={<TopNavBarMenu node={profileNode} />}>
|
<Dropdown overlay={<TopNavBarMenu node={profileNode} />}>
|
||||||
<ToolbarButton
|
<ToolbarButton
|
||||||
@ -73,6 +75,7 @@ const getStyles = (theme: GrafanaTheme2) => {
|
|||||||
display: 'flex',
|
display: 'flex',
|
||||||
gap: theme.spacing(0.5),
|
gap: theme.spacing(0.5),
|
||||||
justifyContent: 'flex-end',
|
justifyContent: 'flex-end',
|
||||||
|
alignItems: 'center',
|
||||||
}),
|
}),
|
||||||
profileButton: css({
|
profileButton: css({
|
||||||
img: {
|
img: {
|
||||||
|
@ -3,37 +3,12 @@ import { Location } from 'history';
|
|||||||
import { GrafanaConfig, locationUtil, NavModelItem } from '@grafana/data';
|
import { GrafanaConfig, locationUtil, NavModelItem } from '@grafana/data';
|
||||||
import { ContextSrv, setContextSrv } from 'app/core/services/context_srv';
|
import { ContextSrv, setContextSrv } from 'app/core/services/context_srv';
|
||||||
|
|
||||||
import { updateConfig } from '../../config';
|
import { enrichConfigItems, getActiveItem, isMatchOrChildMatch, isSearchActive } from './utils';
|
||||||
|
|
||||||
import { enrichConfigItems, getActiveItem, getForcedLoginUrl, isMatchOrChildMatch, isSearchActive } from './utils';
|
|
||||||
|
|
||||||
jest.mock('../../app_events', () => ({
|
jest.mock('../../app_events', () => ({
|
||||||
publish: jest.fn(),
|
publish: jest.fn(),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
describe('getForcedLoginUrl', () => {
|
|
||||||
it.each`
|
|
||||||
appSubUrl | url | expected
|
|
||||||
${''} | ${'/whatever?a=1&b=2'} | ${'/whatever?a=1&b=2&forceLogin=true'}
|
|
||||||
${'/grafana'} | ${'/whatever?a=1&b=2'} | ${'/grafana/whatever?a=1&b=2&forceLogin=true'}
|
|
||||||
${'/grafana/test'} | ${'/whatever?a=1&b=2'} | ${'/grafana/test/whatever?a=1&b=2&forceLogin=true'}
|
|
||||||
${'/grafana'} | ${''} | ${'/grafana?forceLogin=true'}
|
|
||||||
${'/grafana'} | ${'/whatever'} | ${'/grafana/whatever?forceLogin=true'}
|
|
||||||
${'/grafana'} | ${'/whatever/'} | ${'/grafana/whatever/?forceLogin=true'}
|
|
||||||
`(
|
|
||||||
"when appUrl set to '$appUrl' and appSubUrl set to '$appSubUrl' then result should be '$expected'",
|
|
||||||
({ appSubUrl, url, expected }) => {
|
|
||||||
updateConfig({
|
|
||||||
appSubUrl,
|
|
||||||
});
|
|
||||||
|
|
||||||
const result = getForcedLoginUrl(url);
|
|
||||||
|
|
||||||
expect(result).toBe(expected);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('enrichConfigItems', () => {
|
describe('enrichConfigItems', () => {
|
||||||
let mockItems: NavModelItem[];
|
let mockItems: NavModelItem[];
|
||||||
const mockLocation: Location<unknown> = {
|
const mockLocation: Location<unknown> = {
|
||||||
|
@ -1,8 +1,7 @@
|
|||||||
import { Location } from 'history';
|
import { Location } from 'history';
|
||||||
|
|
||||||
import { locationUtil, NavModelItem, NavSection } from '@grafana/data';
|
import { locationUtil, NavModelItem, NavSection } from '@grafana/data';
|
||||||
import { reportInteraction } from '@grafana/runtime';
|
import { config, reportInteraction } from '@grafana/runtime';
|
||||||
import { getConfig } from 'app/core/config';
|
|
||||||
import { contextSrv } from 'app/core/services/context_srv';
|
import { contextSrv } from 'app/core/services/context_srv';
|
||||||
|
|
||||||
import { ShowModalReactEvent } from '../../../types/events';
|
import { ShowModalReactEvent } from '../../../types/events';
|
||||||
@ -16,13 +15,6 @@ export const NAV_MENU_PORTAL_CONTAINER_ID = 'navbar-menu-portal-container';
|
|||||||
|
|
||||||
export const getNavMenuPortalContainer = () => document.getElementById(NAV_MENU_PORTAL_CONTAINER_ID) ?? document.body;
|
export const getNavMenuPortalContainer = () => document.getElementById(NAV_MENU_PORTAL_CONTAINER_ID) ?? document.body;
|
||||||
|
|
||||||
export const getForcedLoginUrl = (url: string) => {
|
|
||||||
const queryParams = new URLSearchParams(url.split('?')[1]);
|
|
||||||
queryParams.append('forceLogin', 'true');
|
|
||||||
|
|
||||||
return `${getConfig().appSubUrl}${url.split('?')[0]}?${queryParams.toString()}`;
|
|
||||||
};
|
|
||||||
|
|
||||||
export const enrichConfigItems = (items: NavModelItem[], location: Location<unknown>) => {
|
export const enrichConfigItems = (items: NavModelItem[], location: Location<unknown>) => {
|
||||||
const { isSignedIn, user } = contextSrv;
|
const { isSignedIn, user } = contextSrv;
|
||||||
const onOpenShortcuts = () => {
|
const onOpenShortcuts = () => {
|
||||||
@ -41,8 +33,8 @@ export const enrichConfigItems = (items: NavModelItem[], location: Location<unkn
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isSignedIn) {
|
if (!isSignedIn && !config.featureToggles.topnav) {
|
||||||
const forcedLoginUrl = getForcedLoginUrl(location.pathname + location.search);
|
const loginUrl = locationUtil.getUrlForPartial(location, { forceLogin: 'true' });
|
||||||
|
|
||||||
items.unshift({
|
items.unshift({
|
||||||
icon: 'signout',
|
icon: 'signout',
|
||||||
@ -50,7 +42,7 @@ export const enrichConfigItems = (items: NavModelItem[], location: Location<unkn
|
|||||||
section: NavSection.Config,
|
section: NavSection.Config,
|
||||||
target: '_self',
|
target: '_self',
|
||||||
text: 'Sign in',
|
text: 'Sign in',
|
||||||
url: forcedLoginUrl,
|
url: loginUrl,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user