mirror of
https://github.com/grafana/grafana.git
synced 2026-09-05 04:40:13 -05:00
Chore: Clean up old navigation (#66287)
* remove code outside of the topnav feature flag * delete NavBar folder * remove topnav toggle from backend * restructure AppChrome folder * fix utils mock * fix applinks tests * remove tests since they're covered in e2e * fix 1 of the approotpage tests * Fix another dashboardpage test * remove reverse portalling + test for plugins using deprecated onNavChanged method * kick drone * handle correlations
This commit is contained in:
@@ -1,54 +0,0 @@
|
||||
import { act, render, screen, waitFor } from '@testing-library/react';
|
||||
import React from 'react';
|
||||
import { Provider } from 'react-redux';
|
||||
import { Router } from 'react-router-dom';
|
||||
|
||||
import { locationService } from '@grafana/runtime/src';
|
||||
import { GrafanaContext } from 'app/core/context/GrafanaContext';
|
||||
|
||||
import { getGrafanaContextMock } from '../../../../../test/mocks/getGrafanaContextMock';
|
||||
import { setStarred } from '../../../../core/reducers/navBarTree';
|
||||
import { configureStore } from '../../../../store/configureStore';
|
||||
import { updateTimeZoneForSession } from '../../../profile/state/reducers';
|
||||
import { createDashboardModelFixture } from '../../state/__fixtures__/dashboardFixtures';
|
||||
|
||||
import { DashNav } from './DashNav';
|
||||
|
||||
describe('Public dashboard title tag', () => {
|
||||
it('will be rendered when publicDashboardEnabled set to true in dashboard meta', async () => {
|
||||
let dashboard = createDashboardModelFixture({}, { publicDashboardEnabled: false });
|
||||
|
||||
const store = configureStore();
|
||||
const context = getGrafanaContextMock();
|
||||
const props = {
|
||||
setStarred: jest.fn() as unknown as typeof setStarred,
|
||||
updateTimeZoneForSession: jest.fn() as unknown as typeof updateTimeZoneForSession,
|
||||
};
|
||||
|
||||
render(
|
||||
<Provider store={store}>
|
||||
<GrafanaContext.Provider value={context}>
|
||||
<Router history={locationService.getHistory()}>
|
||||
<DashNav
|
||||
{...props}
|
||||
dashboard={dashboard}
|
||||
hideTimePicker={true}
|
||||
isFullscreen={false}
|
||||
onAddPanel={() => {}}
|
||||
title="test"
|
||||
/>
|
||||
</Router>
|
||||
</GrafanaContext.Provider>
|
||||
</Provider>
|
||||
);
|
||||
|
||||
const publicTag = screen.queryByText('Public');
|
||||
expect(publicTag).not.toBeInTheDocument();
|
||||
|
||||
act(() => {
|
||||
dashboard.updateMeta({ publicDashboardEnabled: true });
|
||||
});
|
||||
|
||||
await waitFor(() => screen.getByText('Public'));
|
||||
});
|
||||
});
|
||||
@@ -3,14 +3,13 @@ import React, { FC, ReactNode, useContext, useEffect } from 'react';
|
||||
import { connect, ConnectedProps } from 'react-redux';
|
||||
import { useLocation } from 'react-router-dom';
|
||||
|
||||
import { locationUtil, textUtil } from '@grafana/data';
|
||||
import { textUtil } from '@grafana/data';
|
||||
import { selectors as e2eSelectors } from '@grafana/e2e-selectors/src';
|
||||
import { locationService } from '@grafana/runtime';
|
||||
import {
|
||||
ButtonGroup,
|
||||
ModalsController,
|
||||
ToolbarButton,
|
||||
PageToolbar,
|
||||
useForceUpdate,
|
||||
Tag,
|
||||
ToolbarButtonRow,
|
||||
@@ -18,9 +17,8 @@ import {
|
||||
ConfirmModal,
|
||||
} from '@grafana/ui';
|
||||
import { AppChromeUpdate } from 'app/core/components/AppChrome/AppChromeUpdate';
|
||||
import { NavToolbarSeparator } from 'app/core/components/AppChrome/NavToolbarSeparator';
|
||||
import { NavToolbarSeparator } from 'app/core/components/AppChrome/NavToolbar/NavToolbarSeparator';
|
||||
import config from 'app/core/config';
|
||||
import { useGrafana } from 'app/core/context/GrafanaContext';
|
||||
import { useAppNotification } from 'app/core/copy/appNotification';
|
||||
import { appEvents } from 'app/core/core';
|
||||
import { useBusEvent } from 'app/core/hooks/useBusEvent';
|
||||
@@ -79,8 +77,9 @@ export function addCustomRightAction(content: DashNavButtonModel) {
|
||||
type Props = OwnProps & ConnectedProps<typeof connector>;
|
||||
|
||||
export const DashNav = React.memo<Props>((props) => {
|
||||
// this ensures the component rerenders when the location changes
|
||||
useLocation();
|
||||
const forceUpdate = useForceUpdate();
|
||||
const { chrome } = useGrafana();
|
||||
const { showModal, hideModal } = useContext(ModalsContext);
|
||||
|
||||
// We don't really care about the event payload here only that it triggeres a re-render of this component
|
||||
@@ -136,14 +135,6 @@ export const DashNav = React.memo<Props>((props) => {
|
||||
});
|
||||
};
|
||||
|
||||
const onClose = () => {
|
||||
locationService.partial({ viewPanel: null });
|
||||
};
|
||||
|
||||
const onToggleTVMode = () => {
|
||||
chrome.onToggleKioskMode();
|
||||
};
|
||||
|
||||
const onOpenSettings = () => {
|
||||
locationService.partial({ editview: 'settings' });
|
||||
};
|
||||
@@ -287,21 +278,13 @@ export const DashNav = React.memo<Props>((props) => {
|
||||
const { snapshot } = dashboard;
|
||||
const snapshotUrl = snapshot && snapshot.originalUrl;
|
||||
const buttons: ReactNode[] = [];
|
||||
const tvButton = config.featureToggles.topnav ? null : (
|
||||
<ToolbarButton
|
||||
tooltip={t('dashboard.toolbar.tv-button', 'Cycle view mode')}
|
||||
icon="monitor"
|
||||
onClick={onToggleTVMode}
|
||||
key="tv-button"
|
||||
/>
|
||||
);
|
||||
|
||||
if (isPlaylistRunning()) {
|
||||
return [renderPlaylistControls(), renderTimeControls()];
|
||||
}
|
||||
|
||||
if (kioskMode === KioskMode.TV) {
|
||||
return [renderTimeControls(), tvButton];
|
||||
return [renderTimeControls()];
|
||||
}
|
||||
|
||||
if (canEdit && !isFullscreen) {
|
||||
@@ -364,7 +347,6 @@ export const DashNav = React.memo<Props>((props) => {
|
||||
addCustomContent(customRightActions, buttons);
|
||||
|
||||
buttons.push(renderTimeControls());
|
||||
buttons.push(tvButton);
|
||||
|
||||
if (config.featureToggles.scenes) {
|
||||
buttons.push(
|
||||
@@ -379,39 +361,16 @@ export const DashNav = React.memo<Props>((props) => {
|
||||
return buttons;
|
||||
};
|
||||
|
||||
const { isFullscreen, title, folderTitle } = props;
|
||||
// this ensures the component rerenders when the location changes
|
||||
const location = useLocation();
|
||||
const titleHref = locationUtil.getUrlForPartial(location, { search: 'open' });
|
||||
const parentHref = locationUtil.getUrlForPartial(location, { search: 'open', query: 'folder:current' });
|
||||
const onGoBack = isFullscreen ? onClose : undefined;
|
||||
|
||||
if (config.featureToggles.topnav) {
|
||||
return (
|
||||
<AppChromeUpdate
|
||||
actions={
|
||||
<>
|
||||
{renderLeftActions()}
|
||||
<NavToolbarSeparator leftActionsSeparator />
|
||||
<ToolbarButtonRow alignment="right">{renderRightActions()}</ToolbarButtonRow>
|
||||
</>
|
||||
}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<PageToolbar
|
||||
pageIcon={isFullscreen ? undefined : 'apps'}
|
||||
title={title}
|
||||
parent={folderTitle}
|
||||
titleHref={titleHref}
|
||||
parentHref={parentHref}
|
||||
onGoBack={onGoBack}
|
||||
leftItems={renderLeftActions()}
|
||||
>
|
||||
{renderRightActions()}
|
||||
</PageToolbar>
|
||||
<AppChromeUpdate
|
||||
actions={
|
||||
<>
|
||||
{renderLeftActions()}
|
||||
<NavToolbarSeparator leftActionsSeparator />
|
||||
<ToolbarButtonRow alignment="right">{renderRightActions()}</ToolbarButtonRow>
|
||||
</>
|
||||
}
|
||||
/>
|
||||
);
|
||||
});
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ import { useLocation } from 'react-router-dom';
|
||||
import { locationUtil, NavModel, NavModelItem } from '@grafana/data';
|
||||
import { selectors } from '@grafana/e2e-selectors';
|
||||
import { locationService } from '@grafana/runtime';
|
||||
import { Button, PageToolbar, ToolbarButtonRow } from '@grafana/ui';
|
||||
import { Button, ToolbarButtonRow } from '@grafana/ui';
|
||||
import { AppChromeUpdate } from 'app/core/components/AppChrome/AppChromeUpdate';
|
||||
import { Page } from 'app/core/components/PageNew/Page';
|
||||
import config from 'app/core/config';
|
||||
@@ -49,28 +49,25 @@ export function DashboardSettings({ dashboard, editview, pageNav, sectionNav }:
|
||||
dashboard.meta.hasUnsavedFolderChange = false;
|
||||
};
|
||||
|
||||
const folderTitle = dashboard.meta.folderTitle;
|
||||
const currentPage = pages.find((page) => page.id === editview) ?? pages[0];
|
||||
const canSaveAs = contextSrv.hasEditPermissionInFolders;
|
||||
const canSave = dashboard.meta.canSave;
|
||||
const location = useLocation();
|
||||
const editIndex = getEditIndex(location);
|
||||
const subSectionNav = getSectionNav(pageNav, sectionNav, pages, currentPage, location);
|
||||
const size = config.featureToggles.topnav ? 'sm' : 'md';
|
||||
const size = 'sm';
|
||||
|
||||
const actions = [
|
||||
config.featureToggles.topnav && (
|
||||
<Button
|
||||
data-testid={selectors.pages.Dashboard.Settings.Actions.close}
|
||||
variant="secondary"
|
||||
key="close"
|
||||
fill="outline"
|
||||
size={size}
|
||||
onClick={onClose}
|
||||
>
|
||||
Close
|
||||
</Button>
|
||||
),
|
||||
<Button
|
||||
data-testid={selectors.pages.Dashboard.Settings.Actions.close}
|
||||
variant="secondary"
|
||||
key="close"
|
||||
fill="outline"
|
||||
size={size}
|
||||
onClick={onClose}
|
||||
>
|
||||
Close
|
||||
</Button>,
|
||||
canSaveAs && (
|
||||
<SaveDashboardAsButton
|
||||
dashboard={dashboard}
|
||||
@@ -85,13 +82,7 @@ export function DashboardSettings({ dashboard, editview, pageNav, sectionNav }:
|
||||
|
||||
return (
|
||||
<>
|
||||
{!config.featureToggles.topnav ? (
|
||||
<PageToolbar title={`${dashboard.title} / Settings`} parent={folderTitle} onGoBack={onClose}>
|
||||
{actions}
|
||||
</PageToolbar>
|
||||
) : (
|
||||
<AppChromeUpdate actions={<ToolbarButtonRow alignment="right">{actions}</ToolbarButtonRow>} />
|
||||
)}
|
||||
<AppChromeUpdate actions={<ToolbarButtonRow alignment="right">{actions}</ToolbarButtonRow>} />
|
||||
<currentPage.component sectionNav={subSectionNav} dashboard={dashboard} editIndex={editIndex} />
|
||||
</>
|
||||
);
|
||||
|
||||
@@ -7,13 +7,12 @@ import { Subscription } from 'rxjs';
|
||||
import { FieldConfigSource, GrafanaTheme2, NavModel, NavModelItem, PageLayoutType } from '@grafana/data';
|
||||
import { selectors } from '@grafana/e2e-selectors';
|
||||
import { Stack } from '@grafana/experimental';
|
||||
import { config, locationService } from '@grafana/runtime';
|
||||
import { locationService } from '@grafana/runtime';
|
||||
import {
|
||||
Button,
|
||||
HorizontalGroup,
|
||||
InlineSwitch,
|
||||
ModalsController,
|
||||
PageToolbar,
|
||||
RadioButtonGroup,
|
||||
stylesFactory,
|
||||
Themeable2,
|
||||
@@ -322,7 +321,7 @@ export class PanelEditorUnconnected extends PureComponent<Props> {
|
||||
}
|
||||
|
||||
renderEditorActions() {
|
||||
const size = config.featureToggles.topnav ? 'sm' : 'md';
|
||||
const size = 'sm';
|
||||
let editorActions = [
|
||||
<Button
|
||||
onClick={this.onDiscard}
|
||||
@@ -431,18 +430,8 @@ export class PanelEditorUnconnected extends PureComponent<Props> {
|
||||
};
|
||||
|
||||
renderToolbar() {
|
||||
if (config.featureToggles.topnav) {
|
||||
return (
|
||||
<AppChromeUpdate
|
||||
actions={<ToolbarButtonRow alignment="right">{this.renderEditorActions()}</ToolbarButtonRow>}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<PageToolbar title={this.props.dashboard.title} section="Edit Panel" onGoBack={this.onGoBackToDashboard}>
|
||||
{this.renderEditorActions()}
|
||||
</PageToolbar>
|
||||
<AppChromeUpdate actions={<ToolbarButtonRow alignment="right">{this.renderEditorActions()}</ToolbarButtonRow>} />
|
||||
);
|
||||
}
|
||||
|
||||
@@ -514,7 +503,7 @@ export const getStyles = stylesFactory((theme: GrafanaTheme2, props: Props) => {
|
||||
flexGrow: 1,
|
||||
minHeight: 0,
|
||||
display: 'flex',
|
||||
paddingTop: config.featureToggles.topnav ? theme.spacing(2) : 0,
|
||||
paddingTop: theme.spacing(2),
|
||||
}),
|
||||
verticalSplitPanesWrapper: css`
|
||||
display: flex;
|
||||
|
||||
@@ -90,7 +90,7 @@ const mockCleanUpDashboardAndVariables = jest.fn();
|
||||
|
||||
function setup(propOverrides?: Partial<Props>) {
|
||||
config.bootData.navTree = [
|
||||
{ text: 'Dashboards', id: 'dashboards' },
|
||||
{ text: 'Dashboards', id: 'dashboards/browse' },
|
||||
{ text: 'Home', id: HOME_NAV_ID },
|
||||
];
|
||||
|
||||
@@ -101,7 +101,11 @@ function setup(propOverrides?: Partial<Props>) {
|
||||
route: { routeName: DashboardRoutes.Normal } as RouteDescriptor,
|
||||
}),
|
||||
navIndex: {
|
||||
dashboards: { text: 'Dashboards', id: 'dashboards', parentItem: { text: 'Home', id: HOME_NAV_ID } },
|
||||
'dashboards/browse': {
|
||||
text: 'Dashboards',
|
||||
id: 'dashboards/browse',
|
||||
parentItem: { text: 'Home', id: HOME_NAV_ID },
|
||||
},
|
||||
[HOME_NAV_ID]: { text: 'Home', id: HOME_NAV_ID },
|
||||
},
|
||||
initPhase: DashboardInitPhase.NotStarted,
|
||||
@@ -226,27 +230,6 @@ describe('DashboardPage', () => {
|
||||
expect(dashboard.panelInEdit).toBeDefined();
|
||||
});
|
||||
});
|
||||
|
||||
it('Should render panel editor', async () => {
|
||||
const dashboard = getTestDashboard();
|
||||
setup({
|
||||
dashboard,
|
||||
queryParams: { editPanel: '1' },
|
||||
});
|
||||
expect(await screen.findByTitle('Apply changes and go back to dashboard')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('Should reset state when leaving', async () => {
|
||||
const dashboard = getTestDashboard();
|
||||
const { rerender } = setup({
|
||||
dashboard,
|
||||
queryParams: { editPanel: '1' },
|
||||
});
|
||||
rerender({ queryParams: {} });
|
||||
await waitFor(() => {
|
||||
expect(screen.queryByTitle('Apply changes and go back to dashboard')).not.toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('When dashboard unmounts', () => {
|
||||
|
||||
@@ -551,7 +551,7 @@ function updateStatePageNavFromProps(props: Props, state: State): State {
|
||||
pageNav.parentItem = pageNav.parentItem;
|
||||
}
|
||||
} else {
|
||||
sectionNav = getNavModel(props.navIndex, config.featureToggles.topnav ? 'dashboards/browse' : 'dashboards');
|
||||
sectionNav = getNavModel(props.navIndex, 'dashboards/browse');
|
||||
}
|
||||
|
||||
if (state.editPanel || state.viewPanel) {
|
||||
|
||||
Reference in New Issue
Block a user