]> source.dussan.org Git - sonarqube.git/commitdiff
SONARCLOUD-264 Add pages helper with function manage page classes
authorGrégoire Aubert <gregoire.aubert@sonarsource.com>
Tue, 18 Dec 2018 10:19:49 +0000 (11:19 +0100)
committerSonarTech <sonartech@sonarsource.com>
Thu, 20 Dec 2018 10:43:28 +0000 (11:43 +0100)
14 files changed:
server/sonar-web/src/main/js/app/styles/components/page.css
server/sonar-web/src/main/js/apps/about/components/AboutApp.tsx
server/sonar-web/src/main/js/apps/about/sonarcloud/Home.tsx
server/sonar-web/src/main/js/apps/about/sonarcloud/Pricing.tsx
server/sonar-web/src/main/js/apps/about/sonarcloud/components/SQPageContainer.tsx
server/sonar-web/src/main/js/apps/coding-rules/components/App.tsx
server/sonar-web/src/main/js/apps/component-measures/components/App.tsx
server/sonar-web/src/main/js/apps/create/organization/CreateOrganization.tsx
server/sonar-web/src/main/js/apps/create/project/CreateProjectPage.tsx
server/sonar-web/src/main/js/apps/issues/components/App.tsx
server/sonar-web/src/main/js/apps/projects/components/AllProjects.tsx
server/sonar-web/src/main/js/apps/quality-gates/components/QualityGatesApp.tsx
server/sonar-web/src/main/js/apps/web-api/components/WebApiApp.tsx
server/sonar-web/src/main/js/helpers/pages.ts [new file with mode: 0644]

index 994c4d37f30a6f3b17da01c113ca4c25dc45de40..c0c2125fb9eb94ff6ce8d617446bb000e29f3a62 100644 (file)
   color: var(--blue);
 }
 
-.page-footer-with-sidebar {
+.sidebar-page #footer {
   padding-left: calc(50vw - 370px + 10px) !important;
 }
 
-.page-footer-with-sidebar div,
-.page-footer-with-sidebar .page-footer-menu {
+.sidebar-page #footer div,
+.sidebar-page #footer .page-footer-menu {
   max-width: 980px;
 }
 
     left: 301px;
   }
 
-  .page-footer-with-sidebar {
+  .sidebar-page #footer {
     padding-left: 310px !important;
   }
 }
index eb452a2ff8b3a717ff774edcdd3651d69c9f4b0a..5ef36a05dcefec300a5d42d090726a586007b568 100644 (file)
@@ -23,7 +23,6 @@ import { keyBy } from 'lodash';
 import { Link } from 'react-router';
 import { Location } from 'history';
 import AboutProjects from './AboutProjects';
-import EntryIssueTypes from './EntryIssueTypes';
 import AboutLanguages from './AboutLanguages';
 import AboutCleanCode from './AboutCleanCode';
 import AboutQualityModel from './AboutQualityModel';
@@ -31,9 +30,11 @@ import AboutQualityGates from './AboutQualityGates';
 import AboutLeakPeriod from './AboutLeakPeriod';
 import AboutStandards from './AboutStandards';
 import AboutScanners from './AboutScanners';
+import EntryIssueTypes from './EntryIssueTypes';
+import GlobalContainer from '../../../app/components/GlobalContainer';
 import { searchProjects } from '../../../api/components';
 import { getFacet } from '../../../api/issues';
-import GlobalContainer from '../../../app/components/GlobalContainer';
+import { fetchAboutPageSettings } from '../actions';
 import {
   getAppState,
   getCurrentUser,
@@ -41,7 +42,7 @@ import {
   Store
 } from '../../../store/rootReducer';
 import { translate } from '../../../helpers/l10n';
-import { fetchAboutPageSettings } from '../actions';
+import { addWhitePageClass, removeWhitePageClass } from '../../../helpers/pages';
 import '../styles.css';
 
 interface Props {
@@ -69,18 +70,12 @@ class AboutApp extends React.PureComponent<Props, State> {
   componentDidMount() {
     this.mounted = true;
     this.loadData();
-    document.body.classList.add('white-page');
-    if (document.documentElement) {
-      document.documentElement.classList.add('white-page');
-    }
+    addWhitePageClass();
   }
 
   componentWillUnmount() {
     this.mounted = false;
-    document.body.classList.remove('white-page');
-    if (document.documentElement) {
-      document.documentElement.classList.remove('white-page');
-    }
+    removeWhitePageClass();
   }
 
   loadProjects() {
index ff83a9021dd99d12b290015515c49adf1f18ec5f..7d18e25a696d7ba31607972418b9525e33251193 100644 (file)
@@ -22,10 +22,11 @@ import Helmet from 'react-helmet';
 import { FixedNavBar, TopNavBar } from './components/NavBars';
 import FeaturedProjects from './components/FeaturedProjects';
 import Footer from './components/Footer';
-import Statistics from './components/Statistics';
 import { Languages } from './components/Languages';
 import LoginButtons from './components/LoginButtons';
+import Statistics from './components/Statistics';
 import { requestHomepageData, HomepageData, FeaturedProject } from './utils';
+import { addWhitePageClass, removeWhitePageClass } from '../../../helpers/pages';
 import { getBaseUrl } from '../../../helpers/urls';
 import './new_style.css';
 
@@ -37,18 +38,12 @@ export default class Home extends React.PureComponent<{}, State> {
   state: State = {};
 
   componentDidMount() {
-    if (document.documentElement) {
-      document.documentElement.classList.add('white-page');
-    }
-    document.body.classList.add('white-page');
+    addWhitePageClass();
     this.fetchData();
   }
 
   componentWillUnmount() {
-    if (document.documentElement) {
-      document.documentElement.classList.remove('white-page');
-    }
-    document.body.classList.remove('white-page');
+    removeWhitePageClass();
   }
 
   fetchData = () => {
index 76fb85d27709dd11ce229c9c087ec615ad276b2d..5fd1ba25f075ca6461c292e217de45e381359377 100644 (file)
@@ -21,25 +21,20 @@ import * as React from 'react';
 import Helmet from 'react-helmet';
 import Footer from './components/Footer';
 import { TopNavBar, FixedNavBar } from './components/NavBars';
-import { getBaseUrl } from '../../../helpers/urls';
+import { addWhitePageClass, removeWhitePageClass } from '../../../helpers/pages';
 import { scrollToElement } from '../../../helpers/scrolling';
+import { getBaseUrl } from '../../../helpers/urls';
 import './new_style.css';
 
 export default class Pricing extends React.PureComponent {
   container?: HTMLElement | null;
 
   componentDidMount() {
-    if (document.documentElement) {
-      document.documentElement.classList.add('white-page');
-    }
-    document.body.classList.add('white-page');
+    addWhitePageClass();
   }
 
   componentWillUnmount() {
-    if (document.documentElement) {
-      document.documentElement.classList.remove('white-page');
-    }
-    document.body.classList.remove('white-page');
+    removeWhitePageClass();
   }
 
   handleClick = (event: React.MouseEvent) => {
index dee101afa872277dcba2fc0344a7a65c8877f7ef..30aab7a934e4632b9e0a611247ed2201655ab9c1 100644 (file)
@@ -21,8 +21,9 @@ import * as React from 'react';
 import { connect } from 'react-redux';
 import { withRouter, WithRouterProps } from 'react-router';
 import Footer from './Footer';
-import { getCurrentUser, getMyOrganizations, Store } from '../../../../store/rootReducer';
 import GlobalContainer from '../../../../app/components/GlobalContainer';
+import { getCurrentUser, getMyOrganizations, Store } from '../../../../store/rootReducer';
+import { addWhitePageClass, removeWhitePageClass } from '../../../../helpers/pages';
 
 interface StateProps {
   currentUser: T.CurrentUser;
@@ -37,17 +38,11 @@ type Props = StateProps & WithRouterProps & OwnProps;
 
 class SQPageContainer extends React.Component<Props> {
   componentDidMount() {
-    if (document.documentElement) {
-      document.documentElement.classList.add('white-page');
-    }
-    document.body.classList.add('white-page');
+    addWhitePageClass();
   }
 
   componentWillUnmount() {
-    if (document.documentElement) {
-      document.documentElement.classList.remove('white-page');
-    }
-    document.body.classList.remove('white-page');
+    removeWhitePageClass();
   }
 
   render() {
index 7fc402e7416b65e3bad7699ecf5f2afe711eb204..b07d42e815202e02afbb42566bb74ed68558d2de 100644 (file)
@@ -58,11 +58,17 @@ import {
   getAppState
 } from '../../../store/rootReducer';
 import { translate } from '../../../helpers/l10n';
+import { hasPrivateAccess } from '../../../helpers/organizations';
+import {
+  addSideBarClass,
+  addWhitePageClass,
+  removeSideBarClass,
+  removeWhitePageClass
+} from '../../../helpers/pages';
 import { RawQuery } from '../../../helpers/query';
 import { scrollToElement } from '../../../helpers/scrolling';
 import '../../../components/search-navigator.css';
 import '../styles.css';
-import { hasPrivateAccess } from '../../../helpers/organizations';
 
 const PAGE_SIZE = 100;
 const LIMIT_BEFORE_LOAD_MORE = 5;
@@ -114,14 +120,8 @@ export class App extends React.PureComponent<Props, State> {
 
   componentDidMount() {
     this.mounted = true;
-    document.body.classList.add('white-page');
-    if (document.documentElement) {
-      document.documentElement.classList.add('white-page');
-    }
-    const footer = document.getElementById('footer');
-    if (footer) {
-      footer.classList.add('page-footer-with-sidebar');
-    }
+    addWhitePageClass();
+    addSideBarClass();
     this.attachShortcuts();
     this.fetchInitialData();
   }
@@ -153,14 +153,8 @@ export class App extends React.PureComponent<Props, State> {
 
   componentWillUnmount() {
     this.mounted = false;
-    document.body.classList.remove('white-page');
-    if (document.documentElement) {
-      document.documentElement.classList.remove('white-page');
-    }
-    const footer = document.getElementById('footer');
-    if (footer) {
-      footer.classList.remove('page-footer-with-sidebar');
-    }
+    removeWhitePageClass();
+    removeSideBarClass();
     this.detachShortcuts();
   }
 
index 25348fb55db78392838cf3cd9622686f6a74c232..9c1f1eef713bfd362e0e8b8b0a57892ed8c86273 100644 (file)
@@ -49,6 +49,12 @@ import {
   translateWithParameters,
   translate
 } from '../../../helpers/l10n';
+import {
+  addSideBarClass,
+  addWhitePageClass,
+  removeSideBarClass,
+  removeWhitePageClass
+} from '../../../helpers/pages';
 import { RawQuery } from '../../../helpers/query';
 import '../../../components/search-navigator.css';
 import '../style.css';
@@ -107,30 +113,15 @@ export default class App extends React.PureComponent<Props, State> {
 
   componentDidUpdate(_prevProps: Props, prevState: State) {
     if (prevState.measures.length === 0 && this.state.measures.length > 0) {
-      document.body.classList.add('white-page');
-      if (document.documentElement) {
-        document.documentElement.classList.add('white-page');
-      }
-      const footer = document.getElementById('footer');
-      if (footer) {
-        footer.classList.add('page-footer-with-sidebar');
-      }
+      addWhitePageClass();
+      addSideBarClass();
     }
   }
 
   componentWillUnmount() {
     this.mounted = false;
-
-    document.body.classList.remove('white-page');
-    if (document.documentElement) {
-      document.documentElement.classList.remove('white-page');
-    }
-
-    const footer = document.getElementById('footer');
-    if (footer) {
-      footer.classList.remove('page-footer-with-sidebar');
-    }
-
+    removeWhitePageClass();
+    removeSideBarClass();
     key.deleteScope('measures-files');
   }
 
index 9b348bd27170423d098642ad678265577e88aba3..7ccc09db294a7bd588c7f259d2d051185c33833a 100644 (file)
@@ -50,13 +50,14 @@ import {
   listUnboundApplications
 } from '../../../api/alm-integration';
 import { getSubscriptionPlans } from '../../../api/billing';
+import * as api from '../../../api/organizations';
 import { hasAdvancedALMIntegration, isPersonal } from '../../../helpers/almIntegrations';
 import { translate } from '../../../helpers/l10n';
+import { addWhitePageClass, removeWhitePageClass } from '../../../helpers/pages';
 import { get, remove } from '../../../helpers/storage';
 import { slugify } from '../../../helpers/strings';
 import { getOrganizationUrl } from '../../../helpers/urls';
 import { skipOnboarding } from '../../../store/users';
-import * as api from '../../../api/organizations';
 import * as actions from '../../../store/organizations';
 import '../../tutorials/styles.css'; // TODO remove me
 
@@ -104,10 +105,7 @@ export class CreateOrganization extends React.PureComponent<Props & WithRouterPr
 
   componentDidMount() {
     this.mounted = true;
-    document.body.classList.add('white-page');
-    if (document.documentElement) {
-      document.documentElement.classList.add('white-page');
-    }
+    addWhitePageClass();
     const initRequests = [this.fetchSubscriptionPlans()];
     if (hasAdvancedALMIntegration(this.props.currentUser)) {
       initRequests.push(this.fetchAlmApplication());
@@ -137,10 +135,7 @@ export class CreateOrganization extends React.PureComponent<Props & WithRouterPr
 
   componentWillUnmount() {
     this.mounted = false;
-    document.body.classList.remove('white-page');
-    if (document.documentElement) {
-      document.documentElement.classList.remove('white-page');
-    }
+    removeWhitePageClass();
   }
 
   deleteOrganization = () => {
index 12904001e994a472fea4d5f540723caed3bf312d..c5198efe73b2e53b8ffdb4577ffc495615dd8d5a 100644 (file)
@@ -27,11 +27,12 @@ import DeferredSpinner from '../../../components/common/DeferredSpinner';
 import Tabs from '../../../components/controls/Tabs';
 import { whenLoggedIn } from '../../../components/hoc/whenLoggedIn';
 import { withUserOrganizations } from '../../../components/hoc/withUserOrganizations';
-import { skipOnboarding } from '../../../store/users';
 import { getAlmAppInfo } from '../../../api/alm-integration';
 import { hasAdvancedALMIntegration } from '../../../helpers/almIntegrations';
 import { translate } from '../../../helpers/l10n';
+import { addWhitePageClass, removeWhitePageClass } from '../../../helpers/pages';
 import { getProjectUrl, getOrganizationUrl } from '../../../helpers/urls';
+import { skipOnboarding } from '../../../store/users';
 import './style.css';
 
 interface Props {
@@ -64,18 +65,12 @@ export class CreateProjectPage extends React.PureComponent<Props & WithRouterPro
     } else {
       this.setState({ loading: false });
     }
-    document.body.classList.add('white-page');
-    if (document.documentElement) {
-      document.documentElement.classList.add('white-page');
-    }
+    addWhitePageClass();
   }
 
   componentWillUnmount() {
     this.mounted = false;
-    document.body.classList.remove('white-page');
-    if (document.documentElement) {
-      document.documentElement.classList.remove('white-page');
-    }
+    removeWhitePageClass();
   }
 
   handleProjectCreate = (projectKeys: string[], organization?: string) => {
index 275eeb839037256f3b553f4119c63b3dec9efe3c..cc7faa4af897fa5ad2a9467db3a062e0e64cdfdb 100644 (file)
@@ -18,8 +18,8 @@
  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  */
 import * as React from 'react';
-import Helmet from 'react-helmet';
 import * as key from 'keymaster';
+import Helmet from 'react-helmet';
 import { keyBy, omit, union, without } from 'lodash';
 import BulkChangeModal from './BulkChangeModal';
 import ComponentBreadcrumbs from './ComponentBreadcrumbs';
@@ -32,7 +32,6 @@ import PageActions from './PageActions';
 import ConciseIssuesList from '../conciseIssuesList/ConciseIssuesList';
 import ConciseIssuesListHeader from '../conciseIssuesList/ConciseIssuesListHeader';
 import Sidebar from '../sidebar/Sidebar';
-import Suggestions from '../../../app/components/embed-docs-modal/Suggestions';
 import * as actions from '../actions';
 import {
   areMyIssuesSelected,
@@ -52,12 +51,17 @@ import {
   STANDARDS,
   ReferencedRule
 } from '../utils';
-import handleRequiredAuthentication from '../../../app/utils/handleRequiredAuthentication';
+import { Button } from '../../../components/ui/buttons';
+import Checkbox from '../../../components/controls/Checkbox';
+import DeferredSpinner from '../../../components/common/DeferredSpinner';
 import Dropdown from '../../../components/controls/Dropdown';
-import ListFooter from '../../../components/controls/ListFooter';
+import DropdownIcon from '../../../components/icons-components/DropdownIcon';
+import EmptySearch from '../../../components/common/EmptySearch';
 import FiltersHeader from '../../../components/common/FiltersHeader';
+import handleRequiredAuthentication from '../../../app/utils/handleRequiredAuthentication';
+import ListFooter from '../../../components/controls/ListFooter';
 import ScreenPositionHelper from '../../../components/common/ScreenPositionHelper';
-import { Button } from '../../../components/ui/buttons';
+import Suggestions from '../../../app/components/embed-docs-modal/Suggestions';
 import {
   isShortLivingBranch,
   isSameBranchLike,
@@ -67,12 +71,14 @@ import {
 } from '../../../helpers/branches';
 import { translate, translateWithParameters } from '../../../helpers/l10n';
 import { RawQuery } from '../../../helpers/query';
+import {
+  addSideBarClass,
+  addWhitePageClass,
+  removeSideBarClass,
+  removeWhitePageClass
+} from '../../../helpers/pages';
 import { scrollToElement } from '../../../helpers/scrolling';
-import EmptySearch from '../../../components/common/EmptySearch';
-import Checkbox from '../../../components/controls/Checkbox';
-import DropdownIcon from '../../../components/icons-components/DropdownIcon';
 import { isSonarCloud } from '../../../helpers/system';
-import DeferredSpinner from '../../../components/common/DeferredSpinner';
 import { withRouter, Location, Router } from '../../../components/hoc/withRouter';
 import '../../../components/search-navigator.css';
 import '../styles.css';
@@ -164,16 +170,8 @@ export class App extends React.PureComponent<Props, State> {
       return;
     }
 
-    document.body.classList.add('white-page');
-    if (document.documentElement) {
-      document.documentElement.classList.add('white-page');
-    }
-
-    const footer = document.getElementById('footer');
-    if (footer) {
-      footer.classList.add('page-footer-with-sidebar');
-    }
-
+    addWhitePageClass();
+    addSideBarClass();
     this.attachShortcuts();
     this.fetchFirstIssues();
   }
@@ -223,18 +221,9 @@ export class App extends React.PureComponent<Props, State> {
 
   componentWillUnmount() {
     this.detachShortcuts();
-
-    document.body.classList.remove('white-page');
-    if (document.documentElement) {
-      document.documentElement.classList.remove('white-page');
-    }
-
-    const footer = document.getElementById('footer');
-    if (footer) {
-      footer.classList.remove('page-footer-with-sidebar');
-    }
-
     this.mounted = false;
+    removeWhitePageClass();
+    removeSideBarClass();
   }
 
   attachShortcuts() {
index 7c3fa2102a86cded53b2bccfbd3bd0b35c43b82c..94f52fe446189fb27c8d7c1ef99daecb8cbf3d4d 100644 (file)
@@ -23,18 +23,19 @@ import { omitBy } from 'lodash';
 import PageHeader from './PageHeader';
 import ProjectsList from './ProjectsList';
 import PageSidebar from './PageSidebar';
-import Suggestions from '../../../app/components/embed-docs-modal/Suggestions';
-import Visualizations from '../visualizations/Visualizations';
 import handleRequiredAuthentication from '../../../app/utils/handleRequiredAuthentication';
 import DeferredSpinner from '../../../components/common/DeferredSpinner';
 import ListFooter from '../../../components/controls/ListFooter';
 import ScreenPositionHelper from '../../../components/common/ScreenPositionHelper';
-import { translate } from '../../../helpers/l10n';
-import { get, save } from '../../../helpers/storage';
-import { RawQuery } from '../../../helpers/query';
+import Suggestions from '../../../app/components/embed-docs-modal/Suggestions';
+import Visualizations from '../visualizations/Visualizations';
 import { Project, Facets } from '../types';
 import { fetchProjects, parseSorting, SORTING_SWITCH } from '../utils';
 import { parseUrlQuery, Query, hasFilterParams, hasVisualizationParams } from '../query';
+import { translate } from '../../../helpers/l10n';
+import { addSideBarFooterClass, removeSideBarFooterClass } from '../../../helpers/pages';
+import { RawQuery } from '../../../helpers/query';
+import { get, save } from '../../../helpers/storage';
 import { isSonarCloud } from '../../../helpers/system';
 import { isLoggedIn } from '../../../helpers/users';
 import { withRouter, Location, Router } from '../../../components/hoc/withRouter';
@@ -80,10 +81,7 @@ export class AllProjects extends React.PureComponent<Props, State> {
       return;
     }
     this.handleQueryChange(true);
-    const footer = document.getElementById('footer');
-    if (footer) {
-      footer.classList.add('page-footer-with-sidebar');
-    }
+    addSideBarFooterClass();
   }
 
   componentDidUpdate(prevProps: Props) {
@@ -94,11 +92,7 @@ export class AllProjects extends React.PureComponent<Props, State> {
 
   componentWillUnmount() {
     this.mounted = false;
-
-    const footer = document.getElementById('footer');
-    if (footer) {
-      footer.classList.remove('page-footer-with-sidebar');
-    }
+    removeSideBarFooterClass();
   }
 
   getView = () => this.state.query.view || 'overall';
index 8961c35c9c2e32924efcc651c032550d9ab68f9d..f3841a730add3df8c3f3b272a201df030c754219 100644 (file)
@@ -26,6 +26,12 @@ import ScreenPositionHelper from '../../../components/common/ScreenPositionHelpe
 import Suggestions from '../../../app/components/embed-docs-modal/Suggestions';
 import { fetchQualityGates } from '../../../api/quality-gates';
 import { translate } from '../../../helpers/l10n';
+import {
+  addSideBarClass,
+  addWhitePageClass,
+  removeSideBarClass,
+  removeWhitePageClass
+} from '../../../helpers/pages';
 import { getQualityGateUrl } from '../../../helpers/urls';
 import '../../../components/search-navigator.css';
 import '../styles.css';
@@ -51,27 +57,14 @@ class QualityGatesApp extends React.PureComponent<Props, State> {
   componentDidMount() {
     this.mounted = true;
     this.fetchQualityGates();
-
-    document.body.classList.add('white-page');
-    if (document.documentElement) {
-      document.documentElement.classList.add('white-page');
-    }
-    const footer = document.getElementById('footer');
-    if (footer) {
-      footer.classList.add('page-footer-with-sidebar');
-    }
+    addWhitePageClass();
+    addSideBarClass();
   }
 
   componentWillUnmount() {
     this.mounted = false;
-    document.body.classList.remove('white-page');
-    if (document.documentElement) {
-      document.documentElement.classList.remove('white-page');
-    }
-    const footer = document.getElementById('footer');
-    if (footer) {
-      footer.classList.remove('page-footer-with-sidebar');
-    }
+    removeWhitePageClass();
+    removeSideBarClass();
   }
 
   fetchQualityGates = () => {
index 437b2b78fbd68bb2dea0bb2587ebe33a576888e0..9e055ea0372a4128fcdb3a8ab245575fcaf1fc9f 100644 (file)
 import * as React from 'react';
 import Helmet from 'react-helmet';
 import { Link, withRouter, WithRouterProps } from 'react-router';
+import Domain from './Domain';
 import Menu from './Menu';
 import Search from './Search';
-import Domain from './Domain';
-import { Domain as DomainType, fetchWebApi } from '../../../api/web-api';
 import ScreenPositionHelper from '../../../components/common/ScreenPositionHelper';
+import Suggestions from '../../../app/components/embed-docs-modal/Suggestions';
+import { Domain as DomainType, fetchWebApi } from '../../../api/web-api';
 import { getActionKey, isDomainPathActive, Query, serializeQuery, parseQuery } from '../utils';
-import { scrollToElement } from '../../../helpers/scrolling';
 import { translate } from '../../../helpers/l10n';
-import Suggestions from '../../../app/components/embed-docs-modal/Suggestions';
+import { addSideBarClass, removeSideBarClass } from '../../../helpers/pages';
+import { scrollToElement } from '../../../helpers/scrolling';
 import '../styles/web-api.css';
 
 type Props = WithRouterProps;
@@ -44,10 +45,7 @@ class WebApiApp extends React.PureComponent<Props, State> {
   componentDidMount() {
     this.mounted = true;
     this.fetchList();
-    const footer = document.getElementById('footer');
-    if (footer) {
-      footer.classList.add('page-footer-with-sidebar');
-    }
+    addSideBarClass();
   }
 
   componentDidUpdate() {
@@ -57,10 +55,7 @@ class WebApiApp extends React.PureComponent<Props, State> {
 
   componentWillUnmount() {
     this.mounted = false;
-    const footer = document.getElementById('footer');
-    if (footer) {
-      footer.classList.remove('page-footer-with-sidebar');
-    }
+    removeSideBarClass();
   }
 
   fetchList() {
diff --git a/server/sonar-web/src/main/js/helpers/pages.ts b/server/sonar-web/src/main/js/helpers/pages.ts
new file mode 100644 (file)
index 0000000..5258cde
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * 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.
+ */
+
+const CLASS_SIDEBAR_PAGE = 'sidebar-page';
+const CLASS_WHITE_PAGE = 'white-page';
+
+export function addSideBarClass() {
+  toggleBodyClass(CLASS_SIDEBAR_PAGE, true);
+}
+
+export function addWhitePageClass() {
+  toggleBodyClass(CLASS_WHITE_PAGE, true);
+}
+
+export function removeSideBarClass() {
+  toggleBodyClass(CLASS_SIDEBAR_PAGE, false);
+}
+
+export function removeWhitePageClass() {
+  toggleBodyClass(CLASS_WHITE_PAGE, false);
+}
+
+function toggleBodyClass(className: string, force?: boolean) {
+  document.body.classList.toggle(className, force);
+  if (document.documentElement) {
+    document.documentElement.classList.toggle(className, force);
+  }
+}