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:
Ashley Harrison
2023-04-14 09:43:11 +01:00
committed by GitHub
parent 202afb9041
commit 4abe0249ba
108 changed files with 240 additions and 3266 deletions
@@ -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) {