chore: Reduce code duplication by letting the page component adding the header and taking care of the page title

pull/14875/head
Johannes Schill 6 years ago
parent 234713466e
commit 00646b80c6
  1. 41
      public/app/core/components/Page/Page.tsx
  2. 5
      public/app/features/api-keys/ApiKeysPage.tsx
  3. 46
      public/app/features/api-keys/__snapshots__/ApiKeysPage.test.tsx.snap
  4. 5
      public/app/features/datasources/DataSourcesListPage.tsx
  5. 46
      public/app/features/datasources/__snapshots__/DataSourcesListPage.test.tsx.snap
  6. 5
      public/app/features/org/OrgDetailsPage.tsx
  7. 46
      public/app/features/org/__snapshots__/OrgDetailsPage.test.tsx.snap
  8. 5
      public/app/features/plugins/PluginListPage.tsx
  9. 46
      public/app/features/plugins/__snapshots__/PluginListPage.test.tsx.snap
  10. 5
      public/app/features/teams/TeamList.tsx
  11. 46
      public/app/features/teams/__snapshots__/TeamList.test.tsx.snap
  12. 5
      public/app/features/users/UsersListPage.tsx
  13. 46
      public/app/features/users/__snapshots__/UsersListPage.test.tsx.snap

@ -1,6 +1,8 @@
// Libraries
import React, { Component } from 'react';
import config from 'app/core/config';
import { NavModel } from 'app/types';
import { getTitleFromNavModel } from 'app/core/selectors/navModel';
// Components
import PageHeader from '../PageHeader/PageHeader';
@ -11,6 +13,7 @@ import { CustomScrollbar } from '@grafana/ui';
interface Props {
title?: string;
children: JSX.Element[] | JSX.Element;
navModel: NavModel;
}
class Page extends Component<Props> {
@ -35,26 +38,36 @@ class Page extends Component<Props> {
}
updateTitle = () => {
const { title } = this.props;
const title = this.getPageTitle;
document.title = title ? title + ' - Grafana' : 'Grafana';
}
get getPageTitle () {
const { navModel } = this.props;
if (navModel) {
return getTitleFromNavModel(navModel) || undefined;
}
return undefined;
}
render() {
const { navModel } = this.props;
const { buildInfo } = config;
return (
<div className="page-scrollbar-wrapper">
<CustomScrollbar autoHeightMin={'100%'}>
<div className="page-scrollbar-content">
{this.props.children}
<Footer
appName="Grafana"
buildCommit={buildInfo.commit}
buildVersion={buildInfo.version}
newGrafanaVersion={buildInfo.latestVersion}
newGrafanaVersionExists={buildInfo.hasUpdate} />
</div>
</CustomScrollbar>
</div>
<div className="page-scrollbar-wrapper">
<CustomScrollbar autoHeightMin={'100%'}>
<div className="page-scrollbar-content">
<PageHeader model={navModel} />
{this.props.children}
<Footer
appName="Grafana"
buildCommit={buildInfo.commit}
buildVersion={buildInfo.version}
newGrafanaVersion={buildInfo.latestVersion}
newGrafanaVersionExists={buildInfo.hasUpdate} />
</div>
</CustomScrollbar>
</div>
);
}
}

@ -3,7 +3,7 @@ import ReactDOMServer from 'react-dom/server';
import { connect } from 'react-redux';
import { hot } from 'react-hot-loader';
import { NavModel, ApiKey, NewApiKey, OrgRole } from 'app/types';
import { getNavModel, getTitleFromNavModel } from 'app/core/selectors/navModel';
import { getNavModel } from 'app/core/selectors/navModel';
import { getApiKeys, getApiKeysCount } from './state/selectors';
import { loadApiKeys, deleteApiKey, setSearchQuery, addApiKey } from './state/actions';
import Page from 'app/core/components/Page/Page';
@ -239,8 +239,7 @@ export class ApiKeysPage extends PureComponent<Props, any> {
const { hasFetched, navModel, apiKeysCount } = this.props;
return (
<Page title={getTitleFromNavModel(navModel)}>
<Page.Header model={navModel} />
<Page navModel={navModel}>
<Page.Contents isLoading={!hasFetched}>
{hasFetched && (
apiKeysCount > 0 ? (

@ -2,20 +2,17 @@
exports[`Render should render API keys table if there are any keys 1`] = `
<Page
title="Configuration: Api Keys"
>
<PageHeader
model={
Object {
"main": Object {
"text": "Configuration",
},
"node": Object {
"text": "Api Keys",
},
}
navModel={
Object {
"main": Object {
"text": "Configuration",
},
"node": Object {
"text": "Api Keys",
},
}
/>
}
>
<PageContents
isLoading={true}
/>
@ -24,20 +21,17 @@ exports[`Render should render API keys table if there are any keys 1`] = `
exports[`Render should render CTA if there are no API keys 1`] = `
<Page
title="Configuration: Api Keys"
>
<PageHeader
model={
Object {
"main": Object {
"text": "Configuration",
},
"node": Object {
"text": "Api Keys",
},
}
navModel={
Object {
"main": Object {
"text": "Configuration",
},
"node": Object {
"text": "Api Keys",
},
}
/>
}
>
<PageContents
isLoading={false}
>

@ -8,7 +8,7 @@ import DataSourcesList from './DataSourcesList';
import { DataSource, NavModel, StoreState } from 'app/types';
import { LayoutMode } from 'app/core/components/LayoutSelector/LayoutSelector';
import { loadDataSources, setDataSourcesLayoutMode, setDataSourcesSearchQuery } from './state/actions';
import { getNavModel, getTitleFromNavModel } from 'app/core/selectors/navModel';
import { getNavModel } from 'app/core/selectors/navModel';
import {
getDataSources,
@ -67,8 +67,7 @@ export class DataSourcesListPage extends PureComponent<Props> {
};
return (
<Page title={getTitleFromNavModel(navModel)}>
<Page.Header model={navModel} />
<Page navModel={navModel}>
<Page.Contents isLoading={!hasFetched}>
<>
{hasFetched && dataSourcesCount === 0 && <EmptyListCTA model={emptyListModel} />}

@ -2,20 +2,17 @@
exports[`Render should render action bar and datasources 1`] = `
<Page
title="Configuration: Data Sources"
>
<PageHeader
model={
Object {
"main": Object {
"text": "Configuration",
},
"node": Object {
"text": "Data Sources",
},
}
navModel={
Object {
"main": Object {
"text": "Configuration",
},
"node": Object {
"text": "Data Sources",
},
}
/>
}
>
<PageContents
isLoading={false}
>
@ -160,20 +157,17 @@ exports[`Render should render action bar and datasources 1`] = `
exports[`Render should render component 1`] = `
<Page
title="Configuration: Data Sources"
>
<PageHeader
model={
Object {
"main": Object {
"text": "Configuration",
},
"node": Object {
"text": "Data Sources",
},
}
navModel={
Object {
"main": Object {
"text": "Configuration",
},
"node": Object {
"text": "Data Sources",
},
}
/>
}
>
<PageContents
isLoading={true}
/>

@ -6,7 +6,7 @@ import OrgProfile from './OrgProfile';
import SharedPreferences from 'app/core/components/SharedPreferences/SharedPreferences';
import { loadOrganization, setOrganizationName, updateOrganization } from './state/actions';
import { NavModel, Organization, StoreState } from 'app/types';
import { getNavModel, getTitleFromNavModel } from 'app/core/selectors/navModel';
import { getNavModel } from 'app/core/selectors/navModel';
export interface Props {
navModel: NavModel;
@ -34,8 +34,7 @@ export class OrgDetailsPage extends PureComponent<Props> {
const isLoading = Object.keys(organization).length === 0;
return (
<Page title={getTitleFromNavModel(navModel)}>
<Page.Header model={navModel} />
<Page navModel={navModel}>
<Page.Contents isLoading={isLoading}>
<div className="page-container page-body">
{!isLoading && (

@ -2,20 +2,17 @@
exports[`Render should render component 1`] = `
<Page
title="Configuration: Org details"
>
<PageHeader
model={
Object {
"main": Object {
"text": "Configuration",
},
"node": Object {
"text": "Org details",
},
}
navModel={
Object {
"main": Object {
"text": "Configuration",
},
"node": Object {
"text": "Org details",
},
}
/>
}
>
<PageContents
isLoading={true}
>
@ -28,20 +25,17 @@ exports[`Render should render component 1`] = `
exports[`Render should render organization and preferences 1`] = `
<Page
title="Configuration: Org details"
>
<PageHeader
model={
Object {
"main": Object {
"text": "Configuration",
},
"node": Object {
"text": "Org details",
},
}
navModel={
Object {
"main": Object {
"text": "Configuration",
},
"node": Object {
"text": "Org details",
},
}
/>
}
>
<PageContents
isLoading={false}
>

@ -6,7 +6,7 @@ import OrgActionBar from 'app/core/components/OrgActionBar/OrgActionBar';
import PluginList from './PluginList';
import { NavModel, Plugin } from 'app/types';
import { loadPlugins, setPluginsLayoutMode, setPluginsSearchQuery } from './state/actions';
import { getNavModel, getTitleFromNavModel } from 'app/core/selectors/navModel';
import { getNavModel } from 'app/core/selectors/navModel';
import { getLayoutMode, getPlugins, getPluginsSearchQuery } from './state/selectors';
import { LayoutMode } from 'app/core/components/LayoutSelector/LayoutSelector';
@ -47,8 +47,7 @@ export class PluginListPage extends PureComponent<Props> {
};
return (
<Page title={getTitleFromNavModel(navModel)}>
<Page.Header model={navModel} />
<Page navModel={navModel}>
<Page.Contents isLoading={!hasFetched}>
<>
<OrgActionBar

@ -2,20 +2,17 @@
exports[`Render should render component 1`] = `
<Page
title="Configuration: Plugins"
>
<PageHeader
model={
Object {
"main": Object {
"text": "Configuration",
},
"node": Object {
"text": "Plugins",
},
}
navModel={
Object {
"main": Object {
"text": "Configuration",
},
"node": Object {
"text": "Plugins",
},
}
/>
}
>
<PageContents
isLoading={true}
>
@ -37,20 +34,17 @@ exports[`Render should render component 1`] = `
exports[`Render should render list 1`] = `
<Page
title="Configuration: Plugins"
>
<PageHeader
model={
Object {
"main": Object {
"text": "Configuration",
},
"node": Object {
"text": "Plugins",
},
}
navModel={
Object {
"main": Object {
"text": "Configuration",
},
"node": Object {
"text": "Plugins",
},
}
/>
}
>
<PageContents
isLoading={false}
>

@ -7,7 +7,7 @@ import EmptyListCTA from 'app/core/components/EmptyListCTA/EmptyListCTA';
import { NavModel, Team } from 'app/types';
import { loadTeams, deleteTeam, setSearchQuery } from './state/actions';
import { getSearchQuery, getTeams, getTeamsCount } from './state/selectors';
import { getNavModel, getTitleFromNavModel } from 'app/core/selectors/navModel';
import { getNavModel } from 'app/core/selectors/navModel';
export interface Props {
navModel: NavModel;
@ -140,8 +140,7 @@ export class TeamList extends PureComponent<Props, any> {
const { hasFetched, navModel } = this.props;
return (
<Page title={getTitleFromNavModel(navModel)}>
<Page.Header model={navModel} />
<Page navModel={navModel}>
<Page.Contents isLoading={!hasFetched}>
{hasFetched && this.renderList()}
</Page.Contents>

@ -2,20 +2,17 @@
exports[`Render should render component 1`] = `
<Page
title="Configuration: Team List"
>
<PageHeader
model={
Object {
"main": Object {
"text": "Configuration",
},
"node": Object {
"text": "Team List",
},
}
navModel={
Object {
"main": Object {
"text": "Configuration",
},
"node": Object {
"text": "Team List",
},
}
/>
}
>
<PageContents
isLoading={true}
/>
@ -24,20 +21,17 @@ exports[`Render should render component 1`] = `
exports[`Render should render teams table 1`] = `
<Page
title="Configuration: Team List"
>
<PageHeader
model={
Object {
"main": Object {
"text": "Configuration",
},
"node": Object {
"text": "Team List",
},
}
navModel={
Object {
"main": Object {
"text": "Configuration",
},
"node": Object {
"text": "Team List",
},
}
/>
}
>
<PageContents
isLoading={false}
>

@ -9,7 +9,7 @@ import InviteesTable from './InviteesTable';
import { Invitee, NavModel, OrgUser } from 'app/types';
import appEvents from 'app/core/app_events';
import { loadUsers, loadInvitees, setUsersSearchQuery, updateUser, removeUser } from './state/actions';
import { getNavModel, getTitleFromNavModel } from 'app/core/selectors/navModel';
import { getNavModel } from 'app/core/selectors/navModel';
import { getInvitees, getUsers, getUsersSearchQuery } from './state/selectors';
export interface Props {
@ -104,8 +104,7 @@ export class UsersListPage extends PureComponent<Props, State> {
const externalUserMngInfoHtml = this.externalUserMngInfoHtml;
return (
<Page title={getTitleFromNavModel(navModel)}>
<Page.Header model={navModel} />
<Page navModel={navModel}>
<Page.Contents isLoading={!hasFetched}>
<>
<UsersActionBar onShowInvites={this.onShowInvites} showInvites={this.state.showInvites} />

@ -2,20 +2,17 @@
exports[`Render should render List page 1`] = `
<Page
title="Configuration: Users"
>
<PageHeader
model={
Object {
"main": Object {
"text": "Configuration",
},
"node": Object {
"text": "Users",
},
}
navModel={
Object {
"main": Object {
"text": "Configuration",
},
"node": Object {
"text": "Users",
},
}
/>
}
>
<PageContents
isLoading={false}
>
@ -34,20 +31,17 @@ exports[`Render should render List page 1`] = `
exports[`Render should render component 1`] = `
<Page
title="Configuration: Users"
>
<PageHeader
model={
Object {
"main": Object {
"text": "Configuration",
},
"node": Object {
"text": "Users",
},
}
navModel={
Object {
"main": Object {
"text": "Configuration",
},
"node": Object {
"text": "Users",
},
}
/>
}
>
<PageContents
isLoading={true}
>

Loading…
Cancel
Save