mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
PageLayouts: Updates dashboard section routes with navId (#52175)
* First stab at new page layouts behind feature toggle * Simplifying PageHeader * Progress on a new model that can more easily support new and old page layouts * Progress * rename folder * Progress * Minor change * fixes * Fixing tests * Make breadcrumbs work * Add tests for old Page component * Adding tests for new Page component and behavior * fixing page header test * Fixed test * Moving user profile routes to navId * PageLayouts: Updates dashboards routes with navId * added missing navId * AppChrome outside route * Renaming folder * Minor fix * Updated * Fixing StoragePage * Updated * Updating translation ids * Updated snapshot * update nav translation ids (yes this is confusing) Co-authored-by: Ashley Harrison <ashley.harrison@grafana.com> Co-authored-by: joshhunt <josh@trtr.co>
This commit is contained in:
@@ -27,10 +27,6 @@ async function getTestContext({ name, interval, items, uid }: Partial<Playlist>
|
||||
const match: any = { params: { uid: 'foo' } };
|
||||
const location: any = {};
|
||||
const history: any = {};
|
||||
const navModel: any = {
|
||||
node: {},
|
||||
main: {},
|
||||
};
|
||||
const getMock = jest.spyOn(backendSrv, 'get');
|
||||
const putMock = jest.spyOn(backendSrv, 'put');
|
||||
getMock.mockResolvedValue({
|
||||
@@ -40,14 +36,7 @@ async function getTestContext({ name, interval, items, uid }: Partial<Playlist>
|
||||
uid: 'foo',
|
||||
});
|
||||
const { rerender } = render(
|
||||
<PlaylistEditPage
|
||||
queryParams={queryParams}
|
||||
route={route}
|
||||
match={match}
|
||||
location={location}
|
||||
history={history}
|
||||
navModel={navModel}
|
||||
/>
|
||||
<PlaylistEditPage queryParams={queryParams} route={route} match={match} location={location} history={history} />
|
||||
);
|
||||
await waitFor(() => expect(getMock).toHaveBeenCalledTimes(1));
|
||||
|
||||
|
||||
@@ -1,12 +1,8 @@
|
||||
import React, { FC } from 'react';
|
||||
import { connect, MapStateToProps } from 'react-redux';
|
||||
|
||||
import { NavModel } from '@grafana/data';
|
||||
import { locationService } from '@grafana/runtime';
|
||||
import { useStyles2 } from '@grafana/ui';
|
||||
import { Page } from 'app/core/components/Page/Page';
|
||||
import { getNavModel } from 'app/core/selectors/navModel';
|
||||
import { StoreState } from 'app/types';
|
||||
|
||||
import { GrafanaRouteComponentProps } from '../../core/navigation/types';
|
||||
|
||||
@@ -16,17 +12,13 @@ import { getPlaylistStyles } from './styles';
|
||||
import { Playlist } from './types';
|
||||
import { usePlaylist } from './usePlaylist';
|
||||
|
||||
interface ConnectedProps {
|
||||
navModel: NavModel;
|
||||
}
|
||||
|
||||
export interface RouteParams {
|
||||
uid: string;
|
||||
}
|
||||
|
||||
interface Props extends ConnectedProps, GrafanaRouteComponentProps<RouteParams> {}
|
||||
interface Props extends GrafanaRouteComponentProps<RouteParams> {}
|
||||
|
||||
export const PlaylistEditPage: FC<Props> = ({ navModel, match }) => {
|
||||
export const PlaylistEditPage: FC<Props> = ({ match }) => {
|
||||
const styles = useStyles2(getPlaylistStyles);
|
||||
const { playlist, loading } = usePlaylist(match.params.uid);
|
||||
const onSubmit = async (playlist: Playlist) => {
|
||||
@@ -35,7 +27,7 @@ export const PlaylistEditPage: FC<Props> = ({ navModel, match }) => {
|
||||
};
|
||||
|
||||
return (
|
||||
<Page navModel={navModel}>
|
||||
<Page navId="dashboards/playlists">
|
||||
<Page.Contents isLoading={loading}>
|
||||
<h3 className={styles.subHeading}>Edit playlist</h3>
|
||||
|
||||
@@ -50,8 +42,4 @@ export const PlaylistEditPage: FC<Props> = ({ navModel, match }) => {
|
||||
);
|
||||
};
|
||||
|
||||
const mapStateToProps: MapStateToProps<ConnectedProps, {}, StoreState> = (state: StoreState) => ({
|
||||
navModel: getNavModel(state.navIndex, 'playlists'),
|
||||
});
|
||||
|
||||
export default connect(mapStateToProps)(PlaylistEditPage);
|
||||
export default PlaylistEditPage;
|
||||
|
||||
@@ -23,7 +23,7 @@ export const PlaylistForm: FC<PlaylistFormProps> = ({ onSubmit, playlist }) => {
|
||||
const { name, interval, items: propItems } = playlist;
|
||||
const { items, addById, addByTag, deleteItem, moveDown, moveUp } = usePlaylistItems(propItems);
|
||||
return (
|
||||
<>
|
||||
<div>
|
||||
<Form onSubmit={(list: Playlist) => onSubmit({ ...list, items })} validateOn={'onBlur'}>
|
||||
{({ register, errors }) => {
|
||||
const isDisabled = items.length === 0 || Object.keys(errors).length > 0;
|
||||
@@ -81,6 +81,6 @@ export const PlaylistForm: FC<PlaylistFormProps> = ({ onSubmit, playlist }) => {
|
||||
);
|
||||
}}
|
||||
</Form>
|
||||
</>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -30,26 +30,9 @@ jest.mock('../../core/components/TagFilter/TagFilter', () => ({
|
||||
function getTestContext({ name, interval, items }: Partial<Playlist> = {}) {
|
||||
jest.clearAllMocks();
|
||||
const playlist = { name, items, interval } as unknown as Playlist;
|
||||
const queryParams = {};
|
||||
const route: any = {};
|
||||
const match: any = {};
|
||||
const location: any = {};
|
||||
const history: any = {};
|
||||
const navModel: any = {
|
||||
node: {},
|
||||
main: {},
|
||||
};
|
||||
const backendSrvMock = jest.spyOn(backendSrv, 'post');
|
||||
const { rerender } = render(
|
||||
<PlaylistNewPage
|
||||
queryParams={queryParams}
|
||||
route={route}
|
||||
match={match}
|
||||
location={location}
|
||||
history={history}
|
||||
navModel={navModel}
|
||||
/>
|
||||
);
|
||||
|
||||
const { rerender } = render(<PlaylistNewPage />);
|
||||
|
||||
return { playlist, rerender, backendSrvMock };
|
||||
}
|
||||
|
||||
@@ -1,14 +1,8 @@
|
||||
import React, { FC } from 'react';
|
||||
import { connect, MapStateToProps } from 'react-redux';
|
||||
import React from 'react';
|
||||
|
||||
import { NavModel } from '@grafana/data';
|
||||
import { locationService } from '@grafana/runtime';
|
||||
import { useStyles2 } from '@grafana/ui';
|
||||
import { Page } from 'app/core/components/Page/Page';
|
||||
import { getNavModel } from 'app/core/selectors/navModel';
|
||||
import { StoreState } from 'app/types';
|
||||
|
||||
import { GrafanaRouteComponentProps } from '../../core/navigation/types';
|
||||
|
||||
import { PlaylistForm } from './PlaylistForm';
|
||||
import { createPlaylist } from './api';
|
||||
@@ -16,13 +10,7 @@ import { getPlaylistStyles } from './styles';
|
||||
import { Playlist } from './types';
|
||||
import { usePlaylist } from './usePlaylist';
|
||||
|
||||
interface ConnectedProps {
|
||||
navModel: NavModel;
|
||||
}
|
||||
|
||||
interface Props extends ConnectedProps, GrafanaRouteComponentProps {}
|
||||
|
||||
export const PlaylistNewPage: FC<Props> = ({ navModel }) => {
|
||||
export const PlaylistNewPage = () => {
|
||||
const styles = useStyles2(getPlaylistStyles);
|
||||
const { playlist, loading } = usePlaylist();
|
||||
const onSubmit = async (playlist: Playlist) => {
|
||||
@@ -31,7 +19,7 @@ export const PlaylistNewPage: FC<Props> = ({ navModel }) => {
|
||||
};
|
||||
|
||||
return (
|
||||
<Page navModel={navModel}>
|
||||
<Page navId="dashboards/playlists">
|
||||
<Page.Contents isLoading={loading}>
|
||||
<h3 className={styles.subHeading}>New Playlist</h3>
|
||||
|
||||
@@ -46,8 +34,4 @@ export const PlaylistNewPage: FC<Props> = ({ navModel }) => {
|
||||
);
|
||||
};
|
||||
|
||||
const mapStateToProps: MapStateToProps<ConnectedProps, {}, StoreState> = (state: StoreState) => ({
|
||||
navModel: getNavModel(state.navIndex, 'playlists'),
|
||||
});
|
||||
|
||||
export default connect(mapStateToProps)(PlaylistNewPage);
|
||||
export default PlaylistNewPage;
|
||||
|
||||
@@ -3,9 +3,7 @@ import React from 'react';
|
||||
|
||||
import { contextSrv } from 'app/core/services/context_srv';
|
||||
|
||||
import { locationService } from '../../../../packages/grafana-runtime/src';
|
||||
|
||||
import { PlaylistPage, PlaylistPageProps } from './PlaylistPage';
|
||||
import { PlaylistPage } from './PlaylistPage';
|
||||
|
||||
const fnMock = jest.fn();
|
||||
|
||||
@@ -22,29 +20,8 @@ jest.mock('app/core/services/context_srv', () => ({
|
||||
},
|
||||
}));
|
||||
|
||||
function getTestContext(propOverrides?: object) {
|
||||
const props: PlaylistPageProps = {
|
||||
navModel: {
|
||||
main: {
|
||||
text: 'Playlist',
|
||||
},
|
||||
node: {
|
||||
text: 'playlist',
|
||||
},
|
||||
},
|
||||
route: {
|
||||
path: '/playlists',
|
||||
component: jest.fn(),
|
||||
},
|
||||
queryParams: { state: 'ok' },
|
||||
match: { params: { name: 'playlist', sourceName: 'test playlist' }, isExact: false, url: 'asdf', path: '' },
|
||||
history: locationService.getHistory(),
|
||||
location: { pathname: '', hash: '', search: '', state: '' },
|
||||
};
|
||||
|
||||
Object.assign(props, propOverrides);
|
||||
|
||||
return render(<PlaylistPage {...props} />);
|
||||
function getTestContext() {
|
||||
return render(<PlaylistPage />);
|
||||
}
|
||||
|
||||
describe('PlaylistPage', () => {
|
||||
|
||||
@@ -1,17 +1,12 @@
|
||||
import React, { FC, useState } from 'react';
|
||||
import { connect, MapStateToProps } from 'react-redux';
|
||||
import React, { useState } from 'react';
|
||||
import { useDebounce } from 'react-use';
|
||||
|
||||
import { NavModel } from '@grafana/data';
|
||||
import { ConfirmModal } from '@grafana/ui';
|
||||
import { Page } from 'app/core/components/Page/Page';
|
||||
import PageActionBar from 'app/core/components/PageActionBar/PageActionBar';
|
||||
import { getNavModel } from 'app/core/selectors/navModel';
|
||||
import { contextSrv } from 'app/core/services/context_srv';
|
||||
import { StoreState } from 'app/types';
|
||||
|
||||
import EmptyListCTA from '../../core/components/EmptyListCTA/EmptyListCTA';
|
||||
import { GrafanaRouteComponentProps } from '../../core/navigation/types';
|
||||
|
||||
import { EmptyQueryListBanner } from './EmptyQueryListBanner';
|
||||
import { PlaylistPageList } from './PlaylistPageList';
|
||||
@@ -19,12 +14,7 @@ import { StartModal } from './StartModal';
|
||||
import { deletePlaylist, getAllPlaylist } from './api';
|
||||
import { PlaylistDTO } from './types';
|
||||
|
||||
interface ConnectedProps {
|
||||
navModel: NavModel;
|
||||
}
|
||||
export interface PlaylistPageProps extends ConnectedProps, GrafanaRouteComponentProps {}
|
||||
|
||||
export const PlaylistPage: FC<PlaylistPageProps> = ({ navModel }) => {
|
||||
export const PlaylistPage = () => {
|
||||
const [searchQuery, setSearchQuery] = useState('');
|
||||
const [debouncedSearchQuery, setDebouncedSearchQuery] = useState(searchQuery);
|
||||
const [hasFetched, setHasFetched] = useState(false);
|
||||
@@ -76,7 +66,7 @@ export const PlaylistPage: FC<PlaylistPageProps> = ({ navModel }) => {
|
||||
const showSearch = playlists.length > 0 || searchQuery.length > 0 || debouncedSearchQuery.length > 0;
|
||||
|
||||
return (
|
||||
<Page navModel={navModel}>
|
||||
<Page navId="dashboards/playlists">
|
||||
<Page.Contents isLoading={!hasFetched}>
|
||||
{showSearch && (
|
||||
<PageActionBar
|
||||
@@ -112,8 +102,4 @@ export const PlaylistPage: FC<PlaylistPageProps> = ({ navModel }) => {
|
||||
);
|
||||
};
|
||||
|
||||
const mapStateToProps: MapStateToProps<ConnectedProps, {}, StoreState> = (state: StoreState) => ({
|
||||
navModel: getNavModel(state.navIndex, 'playlists'),
|
||||
});
|
||||
|
||||
export default connect(mapStateToProps)(PlaylistPage);
|
||||
export default PlaylistPage;
|
||||
|
||||
Reference in New Issue
Block a user