* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import React from 'react';
+import Helmet from 'react-helmet';
import { connect } from 'react-redux';
import SettingsNav from './nav/settings/SettingsNav';
import { getCurrentUser, getAppState } from '../../store/rootReducer';
import { onFail } from '../../store/rootActions';
import { getSettingsNavigation } from '../../api/nav';
import { setAdminPages } from '../../store/appState/duck';
+import { translate } from '../../helpers/l10n';
class AdminContainer extends React.PureComponent {
componentDidMount() {
return (
<div>
+ <Helmet title={translate('layout.settings')} />
<SettingsNav location={this.props.location} extensions={this.props.adminPages} />
{this.props.children}
</div>
if (this.state.loading) {
return <GlobalLoading />;
}
-
return this.props.children;
}
}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+import React from 'react';
+import Helmet from 'react-helmet';
+
+export default function DefaultHelmetContainer({ children }) {
+ return (
+ <div>
+ <Helmet defaultTitle="SonarQube" />
+ {children}
+ </div>
+ );
+}
},
project?: {
configuration: {},
+ name: string,
qualifier: string
},
fetchProject: string => Promise<*>,
};
render() {
+ const { project } = this.props;
+
// check `breadcrumbs` to be sure that /api/navigation/component has been already called
- if (!this.props.project || this.props.project.breadcrumbs == null) {
+ if (!project || project.breadcrumbs == null) {
return null;
}
- const isFile = ['FIL', 'UTS'].includes(this.props.project.qualifier);
-
- // $FlowFixMe `this.props.project` is always defined at this point
- const configuration = this.props.project.configuration || {};
+ const isFile = ['FIL', 'UTS'].includes(project.qualifier);
+ const configuration = project.configuration || {};
return (
<div>
{!isFile &&
- <ComponentNav
- component={this.props.project}
- conf={configuration}
- location={this.props.location}
- />}
+ <ComponentNav component={project} conf={configuration} location={this.props.location} />}
{/* $FlowFixMe */}
{React.cloneElement(this.props.children, {
- component: this.props.project,
+ component: project,
onComponentChange: this.handleProjectChange
})}
</div>
*/
// @flow
import React from 'react';
+import Helmet from 'react-helmet';
import GlobalPageExtension from './GlobalPageExtension';
+import { translate } from '../../../helpers/l10n';
export default function PortfoliosPage(props: Object) {
return (
- <GlobalPageExtension
- location={props.location}
- params={{ pluginKey: 'governance', extensionKey: 'portfolios' }}
- />
+ <div>
+ <Helmet title={translate('portfolios.page')} />
+ <GlobalPageExtension
+ location={props.location}
+ params={{ pluginKey: 'governance', extensionKey: 'portfolios' }}
+ />
+ </div>
);
}
import { Link } from 'react-router';
import QualifierIcon from '../../../../components/shared/QualifierIcon';
import { getOrganizationByKey, areThereCustomOrganizations } from '../../../../store/rootReducer';
+import OrganizationHelmet from '../../../../components/common/OrganizationHelmet';
import OrganizationLink from '../../../../components/ui/OrganizationLink';
import PrivateBadge from '../../../../components/common/PrivateBadge';
import { collapsePath, limitComponentName } from '../../../../helpers/path';
};
render() {
- const { breadcrumbs, organization, shouldOrganizationBeDisplayed } = this.props;
+ const { breadcrumbs, component, organization, shouldOrganizationBeDisplayed } = this.props;
if (!breadcrumbs) {
return null;
return (
<h2 className="navbar-context-title">
+ <OrganizationHelmet
+ title={component.name}
+ organization={displayOrganization ? organization : null}
+ />
{displayOrganization &&
<span>
<span className="navbar-context-title-qualifier little-spacer-right">
<span className="slash-separator" />
</span>}
{items}
- {this.props.component.visibility === 'private' && <PrivateBadge className="spacer-left" />}
+ {component.visibility === 'private' && <PrivateBadge className="spacer-left" />}
</h2>
);
}
<h2
className="navbar-context-title"
>
+ <OrganizationHelmet
+ organization={null}
+ title="My Project"
+ />
<span>
<span
className="navbar-context-title-qualifier little-spacer-right"
<h2
className="navbar-context-title"
>
+ <OrganizationHelmet
+ organization={
+ Object {
+ "key": "foo",
+ "name": "The Foo Organization",
+ }
+ }
+ title="My Project"
+ />
<span>
<span
className="navbar-context-title-qualifier little-spacer-right"
import { render } from 'react-dom';
import { Router, Route, IndexRoute, Redirect } from 'react-router';
import { Provider } from 'react-redux';
+import DefaultHelmetContainer from '../components/DefaultHelmetContainer';
import LocalizationContainer from '../components/LocalizationContainer';
import MigrationContainer from '../components/MigrationContainer';
import App from '../components/App';
<Route path="markdown/help" component={MarkdownHelp} />
- <Route component={LocalizationContainer}>
- <Route component={SimpleContainer}>
- <Route path="maintenance">{maintenanceRoutes}</Route>
- <Route path="setup">{setupRoutes}</Route>
- </Route>
-
- <Route component={MigrationContainer}>
- <Route component={SimpleSessionsContainer}>
- <Route path="/sessions">{sessionsRoutes}</Route>
+ <Route component={DefaultHelmetContainer}>
+ <Route component={LocalizationContainer}>
+ <Route component={SimpleContainer}>
+ <Route path="maintenance">{maintenanceRoutes}</Route>
+ <Route path="setup">{setupRoutes}</Route>
</Route>
- <Route path="/" component={App}>
-
- <IndexRoute component={Landing} />
-
- <Route component={GlobalContainer}>
- <Route path="about" childRoutes={aboutRoutes} />
- <Route path="account" childRoutes={accountRoutes} />
- <Route path="coding_rules" childRoutes={codingRulesRoutes} />
- <Route path="component" childRoutes={componentRoutes} />
- <Route path="extension/:pluginKey/:extensionKey" component={GlobalPageExtension} />
- <Route path="issues" childRoutes={issuesRoutes} />
- <Route path="organizations" childRoutes={organizationsRoutes} />
- <Route path="projects" childRoutes={projectsRoutes} />
- <Route path="quality_gates" childRoutes={qualityGatesRoutes} />
- <Route path="portfolios" component={PortfoliosPage} />
- <Route path="profiles" childRoutes={qualityProfilesRoutes} />
- <Route path="web_api" childRoutes={webAPIRoutes} />
-
- <Route component={ProjectContainer}>
- <Route path="code" childRoutes={codeRoutes} />
- <Route path="component_measures" childRoutes={componentMeasuresRoutes} />
- <Route path="custom_measures" childRoutes={customMeasuresRoutes} />
- <Route path="dashboard" childRoutes={overviewRoutes} />
- <Route path="project">
- <Route path="activity" childRoutes={projectActivityRoutes} />
- <Route path="admin" component={ProjectAdminContainer}>
+ <Route component={MigrationContainer}>
+ <Route component={SimpleSessionsContainer}>
+ <Route path="/sessions">{sessionsRoutes}</Route>
+ </Route>
+
+ <Route path="/" component={App}>
+
+ <IndexRoute component={Landing} />
+
+ <Route component={GlobalContainer}>
+ <Route path="about" childRoutes={aboutRoutes} />
+ <Route path="account" childRoutes={accountRoutes} />
+ <Route path="coding_rules" childRoutes={codingRulesRoutes} />
+ <Route path="component" childRoutes={componentRoutes} />
+ <Route
+ path="extension/:pluginKey/:extensionKey"
+ component={GlobalPageExtension}
+ />
+ <Route path="issues" childRoutes={issuesRoutes} />
+ <Route path="organizations" childRoutes={organizationsRoutes} />
+ <Route path="projects" childRoutes={projectsRoutes} />
+ <Route path="quality_gates" childRoutes={qualityGatesRoutes} />
+ <Route path="portfolios" component={PortfoliosPage} />
+ <Route path="profiles" childRoutes={qualityProfilesRoutes} />
+ <Route path="web_api" childRoutes={webAPIRoutes} />
+
+ <Route component={ProjectContainer}>
+ <Route path="code" childRoutes={codeRoutes} />
+ <Route path="component_measures" childRoutes={componentMeasuresRoutes} />
+ <Route path="custom_measures" childRoutes={customMeasuresRoutes} />
+ <Route path="dashboard" childRoutes={overviewRoutes} />
+ <Route path="project">
+ <Route path="activity" childRoutes={projectActivityRoutes} />
+ <Route path="admin" component={ProjectAdminContainer}>
+ <Route
+ path="extension/:pluginKey/:extensionKey"
+ component={ProjectAdminPageExtension}
+ />
+ </Route>
+ <Redirect from="extension/governance/governance" to="/view" />
<Route
path="extension/:pluginKey/:extensionKey"
- component={ProjectAdminPageExtension}
+ component={ProjectPageExtension}
/>
+ <Route path="background_tasks" childRoutes={backgroundTasksRoutes} />
+ <Route path="issues" childRoutes={issuesRoutes} />
+ <Route path="settings" childRoutes={settingsRoutes} />
+ {projectAdminRoutes}
</Route>
- <Redirect from="extension/governance/governance" to="/view" />
+ <Route path="project_roles" childRoutes={projectPermissionsRoutes} />
+ <Route path="view" component={ViewDashboard} />
+ </Route>
+
+ <Route component={AdminContainer}>
<Route
- path="extension/:pluginKey/:extensionKey"
- component={ProjectPageExtension}
+ path="admin/extension/:pluginKey/:extensionKey"
+ component={GlobalAdminPageExtension}
/>
<Route path="background_tasks" childRoutes={backgroundTasksRoutes} />
- <Route path="issues" childRoutes={issuesRoutes} />
+ <Route path="groups" childRoutes={groupsRoutes} />
+ <Route path="metrics" childRoutes={metricsRoutes} />
+ <Route path="permission_templates" childRoutes={permissionTemplatesRoutes} />
+ <Route path="projects_admin" childRoutes={projectsAdminRoutes} />
+ <Route path="roles/global" childRoutes={globalPermissionsRoutes} />
<Route path="settings" childRoutes={settingsRoutes} />
- {projectAdminRoutes}
+ <Route path="system" childRoutes={systemRoutes} />
+ <Route path="updatecenter" childRoutes={updateCenterRoutes} />
+ <Route path="users" childRoutes={usersRoutes} />
</Route>
- <Route path="project_roles" childRoutes={projectPermissionsRoutes} />
- <Route path="view" component={ViewDashboard} />
</Route>
- <Route component={AdminContainer}>
- <Route
- path="admin/extension/:pluginKey/:extensionKey"
- component={GlobalAdminPageExtension}
- />
- <Route path="background_tasks" childRoutes={backgroundTasksRoutes} />
- <Route path="groups" childRoutes={groupsRoutes} />
- <Route path="metrics" childRoutes={metricsRoutes} />
- <Route path="permission_templates" childRoutes={permissionTemplatesRoutes} />
- <Route path="projects_admin" childRoutes={projectsAdminRoutes} />
- <Route path="roles/global" childRoutes={globalPermissionsRoutes} />
- <Route path="settings" childRoutes={settingsRoutes} />
- <Route path="system" childRoutes={systemRoutes} />
- <Route path="updatecenter" childRoutes={updateCenterRoutes} />
- <Route path="users" childRoutes={usersRoutes} />
- </Route>
+ <Route path="not_found" component={NotFound} />
+ <Route path="*" component={NotFound} />
</Route>
-
- <Route path="not_found" component={NotFound} />
- <Route path="*" component={NotFound} />
</Route>
</Route>
</Route>
*/
import React from 'react';
import { connect } from 'react-redux';
+import Helmet from 'react-helmet';
import Nav from './Nav';
import UserCard from './UserCard';
import { getCurrentUser, areThereCustomOrganizations } from '../../../store/rootReducer';
+import { translate } from '../../../helpers/l10n';
import handleRequiredAuthentication from '../../../app/utils/handleRequiredAuthentication';
import '../account.css';
return null;
}
+ const title = translate('my_account.page');
return (
<div id="account-page">
+ <Helmet defaultTitle={title} titleTemplate={'%s - ' + title} />
<header className="account-header">
<div className="account-container clearfix">
<UserCard user={currentUser} />
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import React from 'react';
-import { connect } from 'react-redux';
import Helmet from 'react-helmet';
+import { connect } from 'react-redux';
import Password from './Password';
import Tokens from './Tokens';
import { translate } from '../../../helpers/l10n';
function Security(props) {
const { user } = props;
- const title = translate('my_account.page') + ' - ' + translate('my_account.security');
-
return (
<div className="account-body account-container">
- <Helmet title={title} titleTemplate="SonarQube - %s" />
+ <Helmet title={translate('my_account.security')} />
<Tokens user={user} />
}
render() {
- const title = translate('my_account.page') + ' - ' + translate('my_account.notifications');
-
return (
<div className="account-body account-container">
- <Helmet title={title} titleTemplate="SonarQube - %s" />
+ <Helmet title={translate('my_account.notifications')} />
<p className="big-spacer-bottom">
{translate('notification.dispatcher.information')}
className="account-body account-container"
>
<HelmetWrapper
- title="my_account.page - my_account.notifications"
- titleTemplate="SonarQube - %s"
+ title="my_account.notifications"
/>
<p
className="big-spacer-bottom"
}
render() {
- const title = translate('my_account.organizations') + ' - ' + translate('my_account.page');
-
const anyoneCanCreate =
this.props.anyoneCanCreate != null && this.props.anyoneCanCreate.value === 'true';
return (
<div className="account-body account-container">
- <Helmet title={title} titleTemplate="%s - SonarQube" />
+ <Helmet title={translate('my_account.organizations')} />
<header className="page-header">
<h2 className="page-title">{translate('my_account.organizations')}</h2>
}
render() {
+ const helmet = <Helmet title={translate('my_account.projects')} />;
+
if (this.state.projects == null) {
return (
<div className="text-center">
+ {helmet}
<i className="spinner spinner-margin" />
</div>
);
}
- const title = translate('my_account.page') + ' - ' + translate('my_account.projects');
-
return (
<div className="account-body account-container">
- <Helmet title={title} titleTemplate="SonarQube - %s" />
-
+ {helmet}
<Projects
projects={this.state.projects}
total={this.state.total}
*/
// @flow
import React from 'react';
+import Helmet from 'react-helmet';
import { debounce, uniq } from 'lodash';
import { connect } from 'react-redux';
import { DEFAULT_FILTERS, DEBOUNCE_DELAY, STATUSES, CURRENTS } from './../constants';
import { getComponent } from '../../../store/rootReducer';
import '../background-tasks.css';
import { fetchOrganizations } from '../../../store/rootActions';
+import { translate } from '../../../helpers/l10n';
type Props = {
component: Object,
return (
<div className="page page-limited">
+ <Helmet title={translate('background_tasks.page')} />
<Header />
<Stats
*/
import classNames from 'classnames';
import React from 'react';
+import Helmet from 'react-helmet';
import { connect } from 'react-redux';
import Components from './Components';
import Breadcrumbs from './Breadcrumbs';
} from '../utils';
import { addComponent, addComponentBreadcrumbs, clearBucket } from '../bucket';
import { getComponent } from '../../../store/rootReducer';
+import { translate } from '../../../helpers/l10n';
import '../code.css';
class App extends React.PureComponent {
return (
<div className="page page-limited">
+ <Helmet title={translate('code')} />
+
{error &&
<div className="alert alert-danger">
{error}
*/
// @flow
import React from 'react';
+import Helmet from 'react-helmet';
import { connect } from 'react-redux';
import { withRouter } from 'react-router';
import { getAppState } from '../../../store/rootReducer';
+import { translate } from '../../../helpers/l10n';
import init from '../init';
class CodingRulesAppContainer extends React.PureComponent {
// but react wants it to be there to unmount it
return (
<div>
+ <Helmet title={translate('rules')} />
<div ref="container" />
</div>
);
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import React from 'react';
+import Helmet from 'react-helmet';
import Spinner from './../components/Spinner';
+import { translate } from '../../../helpers/l10n';
import '../styles.css';
export default class App extends React.PureComponent {
return (
<main id="component-measures">
+ <Helmet title={translate('layout.measures')} />
{this.props.children}
</main>
);
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import React from 'react';
+import Helmet from 'react-helmet';
import { connect } from 'react-redux';
import init from '../init';
import { getComponent } from '../../../store/rootReducer';
+import { translate } from '../../../helpers/l10n';
class CustomMeasuresAppContainer extends React.PureComponent {
componentDidMount() {
}
render() {
- return <div ref="container" />;
+ return (
+ <div>
+ <Helmet title={translate('custom_measures.page')} />
+ <div ref="container" />
+ </div>
+ );
}
}
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import React from 'react';
+import Helmet from 'react-helmet';
import init from '../init';
+import { translate } from '../../../helpers/l10n';
export default class GroupsAppContainer extends React.PureComponent {
componentDidMount() {
}
render() {
- return <div ref="container" />;
+ return (
+ <div>
+ <Helmet title={translate('user_groups.page')} />
+ <div ref="container" />
+ </div>
+ );
}
}
</div>
);
}
-
render() {
const { component } = this.props;
const { openIssue, paging } = this.state;
-
const selectedIndex = this.getSelectedIndex();
-
return (
<div className="layout-page issues" id="issues-page">
- <Helmet title={translate('issues.page')} titleTemplate="%s - SonarQube" />
+ <Helmet title={translate('issues.page')} />
{this.renderSide(openIssue)}
export type Component = {
key: string,
+ name: string,
organization: string,
qualifier: string
};
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import React from 'react';
+import Helmet from 'react-helmet';
import init from '../init';
+import { translate } from '../../../helpers/l10n';
export default class MetricsAppContainer extends React.PureComponent {
componentDidMount() {
}
render() {
- return <div ref="container" />;
+ return (
+ <div>
+ <Helmet title={translate('custom_metrics.page')} />
+ <div ref="container" />
+ </div>
+ );
}
}
*/
// @flow
import React from 'react';
-import Modal from 'react-modal';
import Helmet from 'react-helmet';
+import Modal from 'react-modal';
import { connect } from 'react-redux';
import { withRouter } from 'react-router';
import { translate } from '../../../helpers/l10n';
render() {
return (
<div className="page page-limited">
- <Helmet
- title={`${translate('organization.delete')} - ${this.props.organization.name}`}
- titleTemplate="%s - SonarQube"
- />
+ <Helmet title={translate('delete')} />
<header className="page-header">
<h1 className="page-title">{translate('organization.delete')}</h1>
*/
// @flow
import React from 'react';
+import Helmet from 'react-helmet';
import { connect } from 'react-redux';
import { debounce } from 'lodash';
import { translate } from '../../../helpers/l10n';
render() {
return (
<div className="page page-limited">
+ <Helmet title={translate('edit')} />
+
<header className="page-header">
<h1 className="page-title">{translate('organization.edit')}</h1>
</header>
// @flow
import React from 'react';
import { connect } from 'react-redux';
-import Helmet from 'react-helmet';
import FavoriteProjectsContainer from '../../projects/components/FavoriteProjectsContainer';
import { getOrganizationByKey } from '../../../store/rootReducer';
import { updateOrganization } from '../actions';
-import { translate } from '../../../helpers/l10n';
class OrganizationFavoriteProjects extends React.PureComponent {
props: {
render() {
return (
<div id="projects-page">
- <Helmet title={translate('projects.page')} titleTemplate="%s - SonarQube" />
<FavoriteProjectsContainer
location={this.props.location}
organization={this.props.organization}
*/
// @flow
import React from 'react';
+import Helmet from 'react-helmet';
import { connect } from 'react-redux';
import init from '../../groups/init';
import { getOrganizationByKey } from '../../../store/rootReducer';
+import { translate } from '../../../helpers/l10n';
import type { Organization } from '../../../store/organizations/duck';
class OrganizationGroups extends React.PureComponent {
}
render() {
- return <div ref="container" />;
+ return (
+ <div>
+ <Helmet title={translate('global_permissions.groups')} />
+ <div ref="container" />
+ </div>
+ );
}
}
*/
// @flow
import React from 'react';
+import Helmet from 'react-helmet';
import MembersPageHeader from './MembersPageHeader';
import MembersListHeader from './MembersListHeader';
import MembersList from './MembersList';
import AddMemberForm from './forms/AddMemberForm';
import ListFooter from '../../../components/controls/ListFooter';
+import { translate } from '../../../helpers/l10n';
import type { Organization, OrgGroup } from '../../../store/organizations/duck';
import type { Member } from '../../../store/organizationsMembers/actions';
const { organization, status, members } = this.props;
return (
<div className="page page-limited">
+ <Helmet title={translate('organization.members.page')} />
<MembersPageHeader loading={status.loading} total={status.total}>
{organization.canAdmin &&
<div className="page-actions">
*/
// @flow
import React from 'react';
+import Helmet from 'react-helmet';
import { connect } from 'react-redux';
import OrganizationNavigation from '../navigation/OrganizationNavigation';
import { fetchOrganization } from '../actions';
return (
<div>
+ <Helmet defaultTitle={organization.name} titleTemplate={'%s - ' + organization.name} />
<OrganizationNavigation organization={organization} location={this.props.location} />
{this.props.children}
</div>
// @flow
import React from 'react';
import { connect } from 'react-redux';
-import Helmet from 'react-helmet';
import AllProjectsContainer from '../../projects/components/AllProjectsContainer';
import { getOrganizationByKey } from '../../../store/rootReducer';
import { updateOrganization } from '../actions';
-import { translate } from '../../../helpers/l10n';
class OrganizationProjects extends React.PureComponent {
props: {
render() {
return (
<div id="projects-page">
- <Helmet title={translate('projects.page')} titleTemplate="%s - SonarQube" />
<AllProjectsContainer
isFavorite={false}
location={this.props.location}
className="page page-limited"
>
<HelmetWrapper
- title="organization.delete - Foo"
- titleTemplate="%s - SonarQube"
+ title="delete"
/>
<header
className="page-header"
className="page page-limited"
>
<HelmetWrapper
- title="organization.delete - Foo"
- titleTemplate="%s - SonarQube"
+ title="delete"
/>
<header
className="page-header"
className="page page-limited"
>
<HelmetWrapper
- title="organization.delete - Foo"
- titleTemplate="%s - SonarQube"
+ title="delete"
/>
<header
className="page-header"
<div
className="page page-limited"
>
+ <HelmetWrapper
+ title="edit"
+ />
<header
className="page-header"
>
<div
className="page page-limited"
>
+ <HelmetWrapper
+ title="edit"
+ />
<header
className="page-header"
>
<div
className="page page-limited"
>
+ <HelmetWrapper
+ title="edit"
+ />
<header
className="page-header"
>
<div
className="page page-limited"
>
+ <HelmetWrapper
+ title="organization.members.page"
+ />
<MembersPageHeader
total={2}
/>
<div
className="page page-limited"
>
+ <HelmetWrapper
+ title="organization.members.page"
+ />
<MembersPageHeader
loading={true}
total={2}
exports[`smoke test 2`] = `
<div>
+ <HelmetWrapper
+ defaultTitle="Foo"
+ titleTemplate="%s - Foo"
+ />
<OrganizationNavigation
organization={
Object {
import React from 'react';
import Home from './Home';
import Template from './Template';
+import OrganizationHelmet from '../../../components/common/OrganizationHelmet';
import { getPermissionTemplates } from '../../../api/permissions';
import { sortPermissions, mergePermissionsToTemplates, mergeDefaultsToTemplates } from '../utils';
+import { translate } from '../../../helpers/l10n';
import '../../permissions/styles.css';
export default class App extends React.PureComponent {
);
}
- render() {
- const { id } = this.props.location.query;
-
- if (id) {
- return this.renderTemplate(id);
- }
-
+ renderHome() {
return (
<Home
organization={this.props.organization}
/>
);
}
+
+ render() {
+ const { id } = this.props.location.query;
+ return (
+ <div>
+ <OrganizationHelmet
+ title={translate('permission_templates.page')}
+ organization={this.props.organization}
+ />
+
+ {id && this.renderTemplate(id)}
+ {!id && this.renderHome()}
+ </div>
+ );
+ }
}
render() {
return (
<div className="page page-limited">
- <Helmet title={translate('permission_templates.page')} titleTemplate="SonarQube - %s" />
+ <Helmet title={translate('permission_templates.page')} />
<Header
organization={this.props.organization}
};
render() {
- const title = translate('permission_templates.page') + ' - ' + this.props.template.name;
-
const permissions = PERMISSIONS_ORDER_FOR_PROJECT.map(p => ({
key: p,
name: translate('projects_role', p),
return (
<div className="page page-limited">
- <Helmet title={title} titleTemplate="SonarQube - %s" />
+ <Helmet title={this.props.template.name} />
<TemplateHeader
organization={this.props.organization}
*/
// @flow
import React from 'react';
+import Helmet from 'react-helmet';
import PageHeader from './PageHeader';
import AllHoldersList from './AllHoldersList';
import PageError from '../../shared/components/PageError';
+import { translate } from '../../../../helpers/l10n';
import '../../styles.css';
-// TODO helmet
-
export default function App(props: { organization?: {} }) {
return (
<div className="page page-limited">
+ <Helmet title={translate('global_permissions.permission')} />
<PageHeader organization={props.organization} />
<PageError />
<AllHoldersList organization={props.organization} />
*/
// @flow
import React from 'react';
+import Helmet from 'react-helmet';
import { without } from 'lodash';
import PageHeader from './PageHeader';
import UpgradeOrganizationBox from '../../../../components/common/UpgradeOrganizationBox';
import PublicProjectDisclaimer from './PublicProjectDisclaimer';
import PageError from '../../shared/components/PageError';
import * as api from '../../../../api/permissions';
+import { translate } from '../../../../helpers/l10n';
import '../../styles.css';
-// TODO helmet
-
export type Props = {|
component: {
configuration?: {
return (
<div className="page page-limited" id="project-permissions-page">
+ <Helmet title={translate('permissions.page')} />
+
<PageHeader
component={this.props.component}
loading={this.state.loading}
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import React from 'react';
+import Helmet from 'react-helmet';
import { connect } from 'react-redux';
import Header from './Header';
import Form from './Form';
import { getComponent } from '../../../store/rootReducer';
+import { translate } from '../../../helpers/l10n';
class Deletion extends React.PureComponent {
static propTypes = {
return (
<div className="page page-limited">
+ <Helmet title={translate('deletion.page')} />
<Header component={this.props.component} />
<Form component={this.props.component} />
</div>
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import React from 'react';
+import Helmet from 'react-helmet';
import { connect } from 'react-redux';
import Header from './Header';
import UpdateForm from './UpdateForm';
return (
<div id="project-key" className="page page-limited">
+ <Helmet title={translate('update_key.page')} />
<Header />
{modules == null && <i className="spinner" />}
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import React from 'react';
+import Helmet from 'react-helmet';
import { connect } from 'react-redux';
import Header from './Header';
import Table from './Table';
import DeletionModal from './views/DeletionModal';
import { fetchProjectLinks, deleteProjectLink, createProjectLink } from '../store/actions';
import { getProjectAdminProjectLinks, getComponent } from '../../../store/rootReducer';
+import { translate } from '../../../helpers/l10n';
class Links extends React.PureComponent {
static propTypes = {
render() {
return (
<div className="page page-limited">
+ <Helmet title={translate('project_links.page')} />
<Header onCreate={this.handleCreateLink} />
<Table links={this.props.links} onDelete={this.handleDeleteLink} />
</div>
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import React from 'react';
+import Helmet from 'react-helmet';
import { connect } from 'react-redux';
import Header from './Header';
import Form from './Form';
getProjectAdminProjectGate,
getComponent
} from '../../../store/rootReducer';
+import { translate } from '../../../helpers/l10n';
class QualityGate extends React.PureComponent {
static propTypes = {
render() {
return (
<div id="project-quality-gate" className="page page-limited">
+ <Helmet title={translate('project_quality_gate.page')} />
<Header />
<Form
allGates={this.props.allGates}
*/
// @flow
import React from 'react';
+import Helmet from 'react-helmet';
import { connect } from 'react-redux';
import Header from './Header';
import Table from './Table';
getProjectAdminProjectProfiles,
getComponent
} from '../../../store/rootReducer';
+import { translate } from '../../../helpers/l10n';
type Props = {
allProfiles: Array<{}>,
return (
<div className="page page-limited">
+ <Helmet title={translate('project_quality_profiles.page')} />
+
<Header />
{profiles.length > 0
*/
// @flow
import React from 'react';
+import Helmet from 'react-helmet';
import { connect } from 'react-redux';
import ProjectActivityPageHeader from './ProjectActivityPageHeader';
import ProjectActivityAnalysesList from './ProjectActivityAnalysesList';
import ProjectActivityPageFooter from './ProjectActivityPageFooter';
import { fetchProjectActivity } from '../actions';
import { getComponent } from '../../../store/rootReducer';
+import { translate } from '../../../helpers/l10n';
import './projectActivity.css';
type Props = {
return (
<div id="project-activity" className="page page-limited">
+ <Helmet title={translate('project_activity.page')} />
+
<ProjectActivityPageHeader
project={project}
filter={this.state.filter}
*/
// @flow
import React from 'react';
+import Helmet from 'react-helmet';
import { debounce, uniq, without } from 'lodash';
import Header from './header';
import Search from './search';
import Projects from './projects';
import CreateProjectForm from './CreateProjectForm';
+import ListFooter from '../../components/controls/ListFooter';
import { PAGE_SIZE, TYPE } from './constants';
import { getComponents, getProvisioned, getGhosts, deleteComponents } from '../../api/components';
-import ListFooter from '../../components/controls/ListFooter';
+import { translate } from '../../helpers/l10n';
import type { Organization } from '../../store/organizations/duck';
type Props = {|
render() {
return (
<div className="page page-limited" id="projects-management-page">
+ <Helmet title={translate('projects_management')} />
+
<Header
hasProvisionPermission={this.props.hasProvisionPermission}
onProjectCreate={this.openCreateProjectForm}
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import React from 'react';
+import Helmet from 'react-helmet';
import PageHeaderContainer from './PageHeaderContainer';
import ProjectsListContainer from './ProjectsListContainer';
import ProjectsListFooterContainer from './ProjectsListFooterContainer';
import PageSidebar from './PageSidebar';
import VisualizationsContainer from '../visualizations/VisualizationsContainer';
import { parseUrlQuery } from '../store/utils';
+import { translate } from '../../../helpers/l10n';
import '../styles.css';
export default class AllProjects extends React.PureComponent {
return (
<div className="layout-page projects-page">
+ <Helmet title={translate('projects.page')} />
<div className="layout-page-side-outer">
<div className="layout-page-side" style={{ top }}>
<div className="layout-page-side-inner">
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import React from 'react';
-import Helmet from 'react-helmet';
-import { translate } from '../../../helpers/l10n';
export default class App extends React.PureComponent {
componentDidMount() {
render() {
return (
<div id="projects-page">
- <Helmet title={translate('projects.page')} titleTemplate="%s - SonarQube" />
{this.props.children}
</div>
);
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import React, { Component } from 'react';
+import Helmet from 'react-helmet';
import {
fetchQualityGate,
setQualityGateAsDefault,
return (
<div className="search-navigator-workspace">
+ <Helmet title={qualityGate.name} />
<DetailsHeader
qualityGate={qualityGate}
edit={edit}
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import React, { Component } from 'react';
+import Helmet from 'react-helmet';
import ListHeader from './ListHeader';
import List from './List';
import {
fetchQualityGatesAppDetails,
fetchQualityGates as fetchQualityGatesAPI
} from '../../../api/quality-gates';
+import { translate } from '../../../helpers/l10n';
import '../styles.css';
export default class QualityGatesApp extends Component {
render() {
const { children, qualityGates, edit } = this.props;
-
+ const defaultTitle = translate('quality_gates.page');
return (
<div className="search-navigator sticky search-navigator-extended-view">
+ <Helmet defaultTitle={defaultTitle} titleTemplate={'%s - ' + defaultTitle} />
+
<div className="search-navigator-side search-navigator-side-light" style={{ top: 30 }}>
<div className="search-navigator-filters">
<ListHeader canEdit={edit} onAdd={this.handleAdd.bind(this)} />
import React from 'react';
import { getQualityProfiles, getExporters } from '../../../api/quality-profiles';
import { sortProfiles } from '../utils';
+import { translate } from '../../../helpers/l10n';
+import OrganizationHelmet from '../../../components/common/OrganizationHelmet';
import type { Exporter } from '../propTypes';
import '../styles.css';
children: React.Element<*>,
currentUser: { permissions: { global: Array<string> } },
languages: Array<*>,
- organization: { canAdmin?: boolean, key: string } | null
+ organization: { name: string, canAdmin?: boolean, key: string } | null
};
type State = {
if (this.state.loading) {
return <i className="spinner" />;
}
-
+ const { organization } = this.props;
const finalLanguages = Object.values(this.props.languages);
- const canAdmin = this.props.organization
- ? this.props.organization.canAdmin
+ const canAdmin = organization
+ ? organization.canAdmin
: this.props.currentUser.permissions.global.includes('profileadmin');
return React.cloneElement(this.props.children, {
languages: finalLanguages,
exporters: this.state.exporters,
updateProfiles: this.updateProfiles,
- organization: this.props.organization ? this.props.organization.key : null,
+ organization: organization ? organization.key : null,
canAdmin
});
}
render() {
return (
<div className="page page-limited">
+ <OrganizationHelmet
+ title={translate('quality_profiles.page')}
+ organization={this.props.organization}
+ />
+
{this.renderChild()}
</div>
);
import Helmet from 'react-helmet';
import ProfileNotFound from './ProfileNotFound';
import ProfileHeader from '../details/ProfileHeader';
-import { translate } from '../../../helpers/l10n';
import type { Profile } from '../propTypes';
type Props = {
...other
});
- const title = translate('quality_profiles.page') + ' - ' + profile.name;
-
return (
<div>
- <Helmet title={title} titleTemplate="SonarQube - %s" />
-
+ <Helmet title={profile.name} />
<ProfileHeader
canAdmin={this.props.canAdmin}
organization={organization}
*/
// @flow
import React from 'react';
-import Helmet from 'react-helmet';
import PageHeader from './PageHeader';
import Evolution from './Evolution';
import ProfilesList from './ProfilesList';
-import { translate } from '../../../helpers/l10n';
import type { Profile } from '../propTypes';
type Props = {
render() {
return (
<div>
- <Helmet title={translate('quality_profiles.page')} titleTemplate="SonarQube - %s" />
-
<PageHeader {...this.props} />
<div className="page-with-sidebar">
*/
// @flow
import React from 'react';
+import Helmet from 'react-helmet';
import { connect } from 'react-redux';
import PageHeader from './PageHeader';
import CategoryDefinitionsList from './CategoryDefinitionsList';
import WildcardsHelp from './WildcardsHelp';
import { fetchSettings } from '../store/actions';
import { getSettingsAppDefaultCategory } from '../../../store/rootReducer';
+import { translate } from '../../../helpers/l10n';
import '../styles.css';
type Props = {
return (
<div id="settings-page" className="page page-limited">
+ <Helmet title={translate('settings.page')} />
+
<PageHeader component={this.props.component} />
<div className="settings-layout">
<div className="settings-side">
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import React from 'react';
+import Helmet from 'react-helmet';
import GenerateSecretKeyForm from './GenerateSecretKeyForm';
import EncryptionForm from './EncryptionForm';
import { translate } from '../../../helpers/l10n';
render() {
return (
<div id="encryption-page" className="page page-limited">
+ <Helmet title={translate('property.category.security.encryption')} />
<header className="page-header">
<h1 className="page-title">{translate('property.category.security.encryption')}</h1>
{this.props.loading && <i className="spinner" />}
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import React from 'react';
+import Helmet from 'react-helmet';
import LicensesAppHeader from './LicensesAppHeader';
import LicensesListContainer from './LicensesListContainer';
+import { translate } from '../../../helpers/l10n';
export default function LicensesApp() {
return (
<div id="licenses-page" className="page page-limited">
+ <Helmet title={translate('property.category.licenses')} />
<LicensesAppHeader />
<LicensesListContainer />
</div>
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import React from 'react';
+import Helmet from 'react-helmet';
import { translate } from '../../../helpers/l10n';
import { getServerId, generateServerId } from '../../../api/settings';
import { parseError } from '../../code/utils';
render() {
return (
<div id="server-id-page" className="page page-limited">
+ <Helmet title={translate('property.category.server_id')} />
<header className="page-header">
<h1 className="page-title">{translate('property.category.server_id')}</h1>
{this.state.loading && <i className="spinner" />}
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import React from 'react';
+import Helmet from 'react-helmet';
import { sortBy } from 'lodash';
import { getSystemInfo } from '../../api/system';
import Section from './section';
return (
<div className="page">
+ <Helmet title={translate('system_info.page')} />
<header className="page-header">
<h1 className="page-title">{translate('system_info.page')}</h1>
<div className="page-actions">
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import React from 'react';
+import Helmet from 'react-helmet';
import { connect } from 'react-redux';
import init from '../init';
import { getSettingValue } from '../../../store/rootReducer';
+import { translate } from '../../../helpers/l10n';
class UpdateCenterAppContainer extends React.PureComponent {
componentDidMount() {
// but react wants it to be there to unmount it
return (
<div>
+ <Helmet title={translate('update_center.page')} />
<div ref="container" />
</div>
);
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import React from 'react';
+import Helmet from 'react-helmet';
import { connect } from 'react-redux';
import init from '../init';
import { getCurrentUser } from '../../../store/rootReducer';
+import { translate } from '../../../helpers/l10n';
class UsersAppContainer extends React.PureComponent {
static propTypes = {
}
render() {
- return <div ref="container" />;
+ return (
+ <div>
+ <Helmet title={translate('users.page')} />
+ <div ref="container" />
+ </div>
+ );
}
}
*/
// @flow
import React from 'react';
+import Helmet from 'react-helmet';
import { Link } from 'react-router';
import { fetchWebApi } from '../../../api/web-api';
import Menu from './Menu';
import Search from './Search';
import Domain from './Domain';
import { getActionKey, isDomainPathActive } from '../utils';
+import { translate } from '../../../helpers/l10n';
import type { Domain as DomainType } from '../../../api/web-api';
import '../styles/web-api.css';
return (
<div className="search-navigator sticky">
+ <Helmet title={translate('api_documentation.page')} />
<div className="search-navigator-side search-navigator-side-light" style={{ top: 30 }}>
<div className="web-api-page-header">
<Link to="/web_api/">
- <h1>Web API</h1>
+ <h1>{translate('api_documentation.page')}</h1>
</Link>
</div>
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+// @flow
+import React from 'react';
+import Helmet from 'react-helmet';
+
+type Props = {
+ title: string,
+ organization?: ?{ name: string }
+};
+
+export default function OrganizationHelmet({ title, organization }: Props) {
+ const defaultTitle = title + (organization ? ' - ' + organization.name : '');
+ return <Helmet defaultTitle={defaultTitle} titleTemplate={'%s - ' + defaultTitle} />;
+}
coding_rules.page=Rules
global_permissions.page=Global Permissions
global_permissions.page.description=Grant and revoke permissions to make changes at the global level. These permissions include editing quality profiles, sharing dashboards, and performing global system administration.
+custom_metrics.page=Custom Metrics
manual_metrics.page=Manual Metrics
manual_metrics.page.description=These metrics are available for all projects. Manual measures can be set at project level via the configuration interface.
manual_metrics.add_manual_metric=Add New Manual Metric