]> source.dussan.org Git - sonarqube.git/commitdiff
SONARCLOUD-93 Fix helmet title sync with GA and add 404 page title
authorGrégoire Aubert <gregoire.aubert@sonarsource.com>
Wed, 18 Jul 2018 08:10:47 +0000 (10:10 +0200)
committerSonarTech <sonartech@sonarsource.com>
Thu, 19 Jul 2018 18:21:25 +0000 (20:21 +0200)
server/sonar-web/src/main/js/app/components/ComponentContainerNotFound.tsx
server/sonar-web/src/main/js/app/components/NotFound.tsx
server/sonar-web/src/main/js/app/components/PageTracker.tsx
server/sonar-web/src/main/js/app/components/extensions/Extension.js
server/sonar-web/src/main/js/app/components/extensions/ExtensionNotFound.tsx [deleted file]
server/sonar-web/src/main/js/app/components/extensions/GlobalAdminPageExtension.js
server/sonar-web/src/main/js/app/components/extensions/GlobalPageExtension.js
server/sonar-web/src/main/js/app/components/extensions/OrganizationPageExtension.tsx
server/sonar-web/src/main/js/app/components/extensions/ProjectAdminPageExtension.js
server/sonar-web/src/main/js/app/components/extensions/ProjectPageExtension.tsx
sonar-core/src/main/resources/org/sonar/l10n/core.properties

index 0542ade62d3f740371052406293eff2476a5773f..d179e67c970a0f720670dad85ca66ff8d181dc8c 100644 (file)
  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  */
 import * as React from 'react';
+import { Helmet } from 'react-helmet';
 import { Link } from 'react-router';
 import { translate } from '../../helpers/l10n';
 
 export default function ComponentContainerNotFound() {
   return (
-    <div id="bd" className="page-wrapper-simple">
-      <div id="nonav" className="page-simple">
-        <h2 className="big-spacer-bottom">{translate('dashboard.project_not_found')}</h2>
-        <p className="spacer-bottom">{translate('dashboard.project_not_found.2')}</p>
-        <p>
-          <Link to="/">Go back to the homepage</Link>
-        </p>
+    <>
+      <Helmet defaultTitle={translate('404_not_found')} defer={false} />
+      <div className="page-wrapper-simple" id="bd">
+        <div className="page-simple" id="nonav">
+          <h2 className="big-spacer-bottom">{translate('dashboard.project_not_found')}</h2>
+          <p className="spacer-bottom">{translate('dashboard.project_not_found.2')}</p>
+          <p>
+            <Link to="/">{translate('go_back_to_homepage')}</Link>
+          </p>
+        </div>
       </div>
-    </div>
+    </>
   );
 }
index ade13464e3978923d64dd58254558b21afca94d8..669f1c8bd0ec3981900c9b4d3fe1ab985b291da9 100644 (file)
  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  */
 import * as React from 'react';
+import { Helmet } from 'react-helmet';
 import { Link } from 'react-router';
 import SimpleContainer from './SimpleContainer';
+import { translate } from '../../helpers/l10n';
 
 interface Props {
   withContainer?: boolean;
@@ -29,14 +31,13 @@ export default function NotFound({ withContainer = true }: Props) {
   const Container = withContainer ? SimpleContainer : React.Fragment;
   return (
     <Container>
+      <Helmet defaultTitle={translate('404_not_found')} defer={false} />
       <div className="page-wrapper-simple" id="bd">
         <div className="page-simple" id="nonav">
-          <h2 className="big-spacer-bottom">The page you were looking for does not exist.</h2>
-          <p className="spacer-bottom">
-            You may have mistyped the address or the page may have moved.
-          </p>
+          <h2 className="big-spacer-bottom">{translate('page_not_found')}</h2>
+          <p className="spacer-bottom">{translate('address_mistyped_or_page_moved')}</p>
           <p>
-            <Link to="/">Go back to the homepage</Link>
+            <Link to="/">{translate('go_back_to_homepage')}</Link>
           </p>
         </div>
       </div>
index e2a4f0c04dd4b7f875004451136a51bb41976f7d..a7699df640fb499dcfa2ba12f10fec4a35a22564 100644 (file)
@@ -49,7 +49,8 @@ export class PageTracker extends React.PureComponent<Props> {
   trackPage = () => {
     const { location, trackingId } = this.props;
     if (trackingId) {
-      GoogleAnalytics.pageview(location.pathname);
+      // More info on the "title and page not in sync" issue: https://github.com/nfl/react-helmet/issues/189
+      setTimeout(() => GoogleAnalytics.pageview(location.pathname), 500);
     }
   };
 
index db2d7080033c72a2a714b9a75eeea0565c8c27da..d2934d309807342dd2e15ecf1375d083a610fb87 100644 (file)
@@ -25,8 +25,6 @@ import { connect } from 'react-redux';
 import { withRouter } from 'react-router';
 import { injectIntl } from 'react-intl';
 import { getExtensionStart } from './utils';
-import { addGlobalErrorMessage } from '../../../store/globalMessages/duck';
-import { getCurrentUser } from '../../../store/rootReducer';
 import { translate } from '../../../helpers/l10n';
 import getStore from '../../utils/getStore';
 
diff --git a/server/sonar-web/src/main/js/app/components/extensions/ExtensionNotFound.tsx b/server/sonar-web/src/main/js/app/components/extensions/ExtensionNotFound.tsx
deleted file mode 100644 (file)
index ca2d702..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2018 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 * as React from 'react';
-import { Link } from 'react-router';
-
-export default function ExtensionNotFound() {
-  return (
-    <div id="bd" className="page-wrapper-simple">
-      <div id="nonav" className="page-simple">
-        <h2 className="big-spacer-bottom">The page you were looking for does not exist.</h2>
-        <p className="spacer-bottom">
-          You may have mistyped the address or the page may have moved.
-        </p>
-        <p>
-          <Link to="/">Go back to the homepage</Link>
-        </p>
-      </div>
-    </div>
-  );
-}
index ba36adf0035499ccbadc37c9222b8c5136176b2a..640ef485c36c6cc9761187424b7bd2bbc1f6ead8 100644 (file)
@@ -21,7 +21,7 @@
 import React from 'react';
 import { connect } from 'react-redux';
 import ExtensionContainer from './ExtensionContainer';
-import ExtensionNotFound from './ExtensionNotFound';
+import NotFound from '../NotFound';
 import { getAppState } from '../../../store/rootReducer';
 
 /*::
@@ -37,7 +37,11 @@ type Props = {
 function GlobalAdminPageExtension(props /*: Props */) {
   const { extensionKey, pluginKey } = props.params;
   const extension = props.adminPages.find(p => p.key === `${pluginKey}/${extensionKey}`);
-  return extension ? <ExtensionContainer extension={extension} /> : <ExtensionNotFound />;
+  return extension ? (
+    <ExtensionContainer extension={extension} />
+  ) : (
+    <NotFound withContainer={false} />
+  );
 }
 
 const mapStateToProps = state => ({
index 248d46f409b9fccd142a13478062a5191b0e4e59..ede95cb92ed67a5a3d9b984689f3f9b70ef2b947 100644 (file)
@@ -21,7 +21,7 @@
 import React from 'react';
 import { connect } from 'react-redux';
 import ExtensionContainer from './ExtensionContainer';
-import ExtensionNotFound from './ExtensionNotFound';
+import NotFound from '../NotFound';
 import { getAppState } from '../../../store/rootReducer';
 
 /*::
@@ -37,7 +37,11 @@ type Props = {
 function GlobalPageExtension(props /*: Props */) {
   const { extensionKey, pluginKey } = props.params;
   const extension = props.globalPages.find(p => p.key === `${pluginKey}/${extensionKey}`);
-  return extension ? <ExtensionContainer extension={extension} /> : <ExtensionNotFound />;
+  return extension ? (
+    <ExtensionContainer extension={extension} />
+  ) : (
+    <NotFound withContainer={false} />
+  );
 }
 
 const mapStateToProps = state => ({
index fd058d429bb8a02d1c88be67b8c26225afe0befb..d5875a4f851b6711992798b3465256bc3bb3f7df 100644 (file)
@@ -20,7 +20,7 @@
 import * as React from 'react';
 import { connect } from 'react-redux';
 import ExtensionContainer from './ExtensionContainer';
-import ExtensionNotFound from './ExtensionNotFound';
+import NotFound from '../NotFound';
 import { getOrganizationByKey } from '../../../store/rootReducer';
 import { fetchOrganization } from '../../../apps/organizations/actions';
 import { Organization } from '../../types';
@@ -69,7 +69,7 @@ class OrganizationPageExtension extends React.PureComponent<Props> {
         options={{ organization, refreshOrganization: this.refreshOrganization }}
       />
     ) : (
-      <ExtensionNotFound />
+      <NotFound withContainer={false} />
     );
   }
 }
index 52c394fbf1b5134fedacf2fde457256e3afa5496..1c584fc30ee9b6dfb714f44cf2b2da5bafe99c4e 100644 (file)
@@ -21,7 +21,7 @@
 import React from 'react';
 import { connect } from 'react-redux';
 import ExtensionContainer from './ExtensionContainer';
-import ExtensionNotFound from './ExtensionNotFound';
+import NotFound from '../NotFound';
 import { addGlobalErrorMessage } from '../../../store/globalMessages/duck';
 
 /*::
@@ -48,7 +48,7 @@ function ProjectAdminPageExtension(props /*: Props */) {
   return extension ? (
     <ExtensionContainer extension={extension} options={{ component }} />
   ) : (
-    <ExtensionNotFound />
+    <NotFound withContainer={false} />
   );
 }
 
index 68c4c5db03e6ed4ccbb96f6a8d18c6f32c539ac2..df6c0f88e905dc3d390d4e1024feb3631bdf2fa1 100644 (file)
@@ -19,7 +19,7 @@
  */
 import * as React from 'react';
 import ExtensionContainer from './ExtensionContainer';
-import ExtensionNotFound from './ExtensionNotFound';
+import NotFound from '../NotFound';
 import { Component } from '../../types';
 
 interface Props {
@@ -40,6 +40,6 @@ export default function ProjectPageExtension(props: Props) {
   return extension ? (
     <ExtensionContainer extension={extension} options={{ component }} />
   ) : (
-    <ExtensionNotFound />
+    <NotFound withContainer={false} />
   );
 }
index 84c3e1fa803e2a0385b8c2209e8ab22e212bb324..e007b3aea60e9ed2d06c83dcf0e990c207966423 100644 (file)
@@ -200,6 +200,8 @@ no=No
 #
 #------------------------------------------------------------------------------
 
+404_not_found=404 Not found
+address_mistyped_or_page_moved=You may have mistyped the address or the page may have moved.
 and_worse=and worse
 are_you_sure=Are you sure?
 as_explained_here=as explained here
@@ -215,6 +217,7 @@ default_error_message=The request cannot be processed. Try again later.
 default_severity=Default severity
 edit_permissions=Edit Permissions
 false_positive=False positive
+go_back_to_homepage=Go back to the homepage
 last_analysis_before=Last analysis before
 logging_out=You're logging out, please wait...
 manage=Manage
@@ -230,6 +233,7 @@ no_results_search.favorites=We couldn't find any results matching selected crite
 no_results_search.2=Try to change filters to get some results.
 no_results_search.favorites.2=Would you like to search among {url} projects?
 page_extension_failed=Page extension failed.
+page_not_found=The page you were looking for does not exist.
 please_contact_administrator=Please contact the instance administrator.
 set_as_default=Set as Default
 short_number_suffix.g=G