mirror of
https://github.com/grafana/grafana.git
synced 2026-09-05 04:40:13 -05:00
TopNav: New page layouts (#51510)
* 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 * AppChrome outside route * Renaming folder * Minor fix * Updated * Fixing StoragePage * Fix for banners Co-authored-by: Ashley Harrison <ashley.harrison@grafana.com>
This commit is contained in:
co-authored by
Ashley Harrison
parent
663f3fcd2a
commit
1e85a6f4fd
@@ -2,9 +2,9 @@ import { render, screen, waitFor } from '@testing-library/react';
|
||||
import userEvent from '@testing-library/user-event';
|
||||
import React from 'react';
|
||||
|
||||
import { NavModel } from '@grafana/data';
|
||||
import { BackendSrv, setBackendSrv } from '@grafana/runtime';
|
||||
|
||||
import { CreateTeam, Props } from './CreateTeam';
|
||||
import { CreateTeam } from './CreateTeam';
|
||||
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks();
|
||||
@@ -14,23 +14,12 @@ const mockPost = jest.fn(() => {
|
||||
return Promise.resolve({});
|
||||
});
|
||||
|
||||
jest.mock('@grafana/runtime', () => ({
|
||||
getBackendSrv: () => {
|
||||
return {
|
||||
post: mockPost,
|
||||
};
|
||||
},
|
||||
config: {
|
||||
buildInfo: {},
|
||||
licenseInfo: {},
|
||||
},
|
||||
}));
|
||||
setBackendSrv({
|
||||
post: mockPost,
|
||||
} as any as BackendSrv);
|
||||
|
||||
const setup = () => {
|
||||
const props: Props = {
|
||||
navModel: { node: {}, main: {} } as NavModel,
|
||||
};
|
||||
return render(<CreateTeam {...props} />);
|
||||
return render(<CreateTeam />);
|
||||
};
|
||||
|
||||
describe('Create team', () => {
|
||||
|
||||
@@ -1,24 +1,16 @@
|
||||
import React, { PureComponent } from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
|
||||
import { NavModel } from '@grafana/data';
|
||||
import { getBackendSrv, locationService } from '@grafana/runtime';
|
||||
import { Button, Form, Field, Input, FieldSet } from '@grafana/ui';
|
||||
import Page from 'app/core/components/Page/Page';
|
||||
import { Page } from 'app/core/components/Page/Page';
|
||||
import { contextSrv } from 'app/core/core';
|
||||
import { getNavModel } from 'app/core/selectors/navModel';
|
||||
import { StoreState } from 'app/types';
|
||||
|
||||
export interface Props {
|
||||
navModel: NavModel;
|
||||
}
|
||||
|
||||
interface TeamDTO {
|
||||
name: string;
|
||||
email: string;
|
||||
}
|
||||
|
||||
export class CreateTeam extends PureComponent<Props> {
|
||||
export class CreateTeam extends PureComponent {
|
||||
create = async (formModel: TeamDTO) => {
|
||||
const result = await getBackendSrv().post('/api/teams', formModel);
|
||||
if (result.teamId) {
|
||||
@@ -27,10 +19,8 @@ export class CreateTeam extends PureComponent<Props> {
|
||||
}
|
||||
};
|
||||
render() {
|
||||
const { navModel } = this.props;
|
||||
|
||||
return (
|
||||
<Page navModel={navModel}>
|
||||
<Page navId="teams">
|
||||
<Page.Contents>
|
||||
<Form onSubmit={this.create}>
|
||||
{({ register, errors }) => (
|
||||
@@ -58,10 +48,4 @@ export class CreateTeam extends PureComponent<Props> {
|
||||
}
|
||||
}
|
||||
|
||||
function mapStateToProps(state: StoreState) {
|
||||
return {
|
||||
navModel: getNavModel(state.navIndex, 'teams'),
|
||||
};
|
||||
}
|
||||
|
||||
export default connect(mapStateToProps)(CreateTeam);
|
||||
export default CreateTeam;
|
||||
|
||||
@@ -3,7 +3,6 @@ import userEvent from '@testing-library/user-event';
|
||||
import React from 'react';
|
||||
import { mockToolkitActionCreator } from 'test/core/redux/mocks';
|
||||
|
||||
import { NavModel } from '@grafana/data';
|
||||
import { contextSrv, User } from 'app/core/services/context_srv';
|
||||
|
||||
import { OrgRole, Team } from '../../types';
|
||||
@@ -20,14 +19,6 @@ jest.mock('app/core/config', () => {
|
||||
|
||||
const setup = (propOverrides?: object) => {
|
||||
const props: Props = {
|
||||
navModel: {
|
||||
main: {
|
||||
text: 'Configuration',
|
||||
},
|
||||
node: {
|
||||
text: 'Team List',
|
||||
},
|
||||
} as NavModel,
|
||||
teams: [] as Team[],
|
||||
loadTeams: jest.fn(),
|
||||
deleteTeam: jest.fn(),
|
||||
|
||||
@@ -1,13 +1,11 @@
|
||||
import React, { PureComponent } from 'react';
|
||||
|
||||
import { NavModel } from '@grafana/data';
|
||||
import { DeleteButton, LinkButton, FilterInput, VerticalGroup, HorizontalGroup, Pagination } from '@grafana/ui';
|
||||
import EmptyListCTA from 'app/core/components/EmptyListCTA/EmptyListCTA';
|
||||
import Page from 'app/core/components/Page/Page';
|
||||
import { Page } from 'app/core/components/Page/Page';
|
||||
import { TeamRolePicker } from 'app/core/components/RolePicker/TeamRolePicker';
|
||||
import { fetchRoleOptions } from 'app/core/components/RolePicker/api';
|
||||
import { config } from 'app/core/config';
|
||||
import { getNavModel } from 'app/core/selectors/navModel';
|
||||
import { contextSrv, User } from 'app/core/services/context_srv';
|
||||
import { AccessControlAction, Role, StoreState, Team } from 'app/types';
|
||||
|
||||
@@ -20,7 +18,6 @@ import { getSearchQuery, getTeams, getTeamsCount, getTeamsSearchPage, isPermissi
|
||||
const pageLimit = 30;
|
||||
|
||||
export interface Props {
|
||||
navModel: NavModel;
|
||||
teams: Team[];
|
||||
searchQuery: string;
|
||||
searchPage: number;
|
||||
@@ -224,10 +221,10 @@ export class TeamList extends PureComponent<Props, State> {
|
||||
}
|
||||
|
||||
render() {
|
||||
const { hasFetched, navModel } = this.props;
|
||||
const { hasFetched } = this.props;
|
||||
|
||||
return (
|
||||
<Page navModel={navModel}>
|
||||
<Page navId="teams">
|
||||
<Page.Contents isLoading={!hasFetched}>{this.renderList()}</Page.Contents>
|
||||
</Page>
|
||||
);
|
||||
@@ -236,7 +233,6 @@ export class TeamList extends PureComponent<Props, State> {
|
||||
|
||||
function mapStateToProps(state: StoreState) {
|
||||
return {
|
||||
navModel: getNavModel(state.navIndex, 'teams'),
|
||||
teams: getTeams(state.teams),
|
||||
searchQuery: getSearchQuery(state.teams),
|
||||
searchPage: getTeamsSearchPage(state.teams),
|
||||
|
||||
@@ -2,7 +2,7 @@ import { render, screen } from '@testing-library/react';
|
||||
import React from 'react';
|
||||
import { Provider } from 'react-redux';
|
||||
|
||||
import { NavModel, createTheme } from '@grafana/data';
|
||||
import { createTheme } from '@grafana/data';
|
||||
import { getRouteComponentProps } from 'app/core/navigation/__mocks__/routeProps';
|
||||
import { User } from 'app/core/services/context_srv';
|
||||
import { configureStore } from 'app/store/configureStore';
|
||||
@@ -68,7 +68,7 @@ const setup = (propOverrides?: object) => {
|
||||
},
|
||||
} as any,
|
||||
}),
|
||||
navModel: { node: {}, main: {} } as NavModel,
|
||||
pageNav: { text: 'Cool team ' },
|
||||
teamId: 1,
|
||||
loadTeam: jest.fn(),
|
||||
loadTeamMembers: jest.fn(),
|
||||
|
||||
@@ -2,10 +2,10 @@ import { includes } from 'lodash';
|
||||
import React, { PureComponent } from 'react';
|
||||
import { connect, ConnectedProps } from 'react-redux';
|
||||
|
||||
import { NavModel } from '@grafana/data';
|
||||
import { NavModelItem } from '@grafana/data';
|
||||
import { featureEnabled } from '@grafana/runtime';
|
||||
import { Themeable2, withTheme2 } from '@grafana/ui';
|
||||
import Page from 'app/core/components/Page/Page';
|
||||
import { Page } from 'app/core/components/Page/Page';
|
||||
import { UpgradeBox } from 'app/core/components/Upgrade/UpgradeBox';
|
||||
import config from 'app/core/config';
|
||||
import { GrafanaRouteComponentProps } from 'app/core/navigation/types';
|
||||
@@ -51,11 +51,11 @@ function mapStateToProps(state: StoreState, props: OwnProps) {
|
||||
}
|
||||
const pageName = props.match.params.page ?? defaultPage;
|
||||
const teamLoadingNav = getTeamLoadingNav(pageName as string);
|
||||
const navModel = getNavModel(state.navIndex, `team-${pageName}-${teamId}`, teamLoadingNav);
|
||||
const pageNav = getNavModel(state.navIndex, `team-${pageName}-${teamId}`, teamLoadingNav).main;
|
||||
const members = getTeamMembers(state.team);
|
||||
|
||||
return {
|
||||
navModel,
|
||||
pageNav,
|
||||
teamId: teamId,
|
||||
pageName: pageName,
|
||||
team,
|
||||
@@ -118,20 +118,20 @@ export class TeamPages extends PureComponent<Props, State> {
|
||||
return text1.toLocaleLowerCase() === text2.toLocaleLowerCase();
|
||||
};
|
||||
|
||||
hideTabsFromNonTeamAdmin = (navModel: NavModel, isSignedInUserTeamAdmin: boolean) => {
|
||||
hideTabsFromNonTeamAdmin = (pageNav: NavModelItem, isSignedInUserTeamAdmin: boolean) => {
|
||||
if (contextSrv.accessControlEnabled()) {
|
||||
return navModel;
|
||||
return pageNav;
|
||||
}
|
||||
|
||||
if (!isSignedInUserTeamAdmin && navModel.main && navModel.main.children) {
|
||||
navModel.main.children
|
||||
if (!isSignedInUserTeamAdmin && pageNav && pageNav.children) {
|
||||
pageNav.children
|
||||
.filter((navItem) => !this.textsAreEqual(navItem.text, PageTypes.Members))
|
||||
.map((navItem) => {
|
||||
navItem.hideFromTabs = true;
|
||||
});
|
||||
}
|
||||
|
||||
return navModel;
|
||||
return pageNav;
|
||||
};
|
||||
|
||||
renderPage(isSignedInUserTeamAdmin: boolean): React.ReactNode {
|
||||
@@ -183,11 +183,11 @@ export class TeamPages extends PureComponent<Props, State> {
|
||||
}
|
||||
|
||||
render() {
|
||||
const { team, navModel, members, editorsCanAdmin, signedInUser } = this.props;
|
||||
const { team, pageNav, members, editorsCanAdmin, signedInUser } = this.props;
|
||||
const isTeamAdmin = isSignedInUserTeamAdmin({ members, editorsCanAdmin, signedInUser });
|
||||
|
||||
return (
|
||||
<Page navModel={this.hideTabsFromNonTeamAdmin(navModel, isTeamAdmin)}>
|
||||
<Page navId="teams" pageNav={this.hideTabsFromNonTeamAdmin(pageNav, isTeamAdmin)}>
|
||||
<Page.Contents isLoading={this.state.isLoading}>
|
||||
{team && Object.keys(team).length !== 0 && this.renderPage(isTeamAdmin)}
|
||||
</Page.Contents>
|
||||
|
||||
@@ -18,7 +18,7 @@ const TeamPermissions = (props: TeamPermissionsProps) => {
|
||||
|
||||
return (
|
||||
<Permissions
|
||||
title="Members"
|
||||
title=""
|
||||
addPermissionTitle="Add member"
|
||||
buttonLabel="Add member"
|
||||
resource="teams"
|
||||
|
||||
Reference in New Issue
Block a user