]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-9583 Use fixed width layout for navigation
authorStas Vilchik <stas.vilchik@sonarsource.com>
Wed, 19 Jul 2017 14:56:38 +0000 (16:56 +0200)
committerStas Vilchik <stas.vilchik@sonarsource.com>
Fri, 21 Jul 2017 14:14:07 +0000 (16:14 +0200)
51 files changed:
server/sonar-web/pom.xml
server/sonar-web/src/main/js/app/components/GlobalContainer.js
server/sonar-web/src/main/js/app/components/SimpleContainer.js
server/sonar-web/src/main/js/app/components/nav/component/ComponentNav.css [new file with mode: 0644]
server/sonar-web/src/main/js/app/components/nav/component/ComponentNav.js
server/sonar-web/src/main/js/app/components/nav/component/ComponentNavBreadcrumbs.js
server/sonar-web/src/main/js/app/components/nav/component/ComponentNavMenu.js
server/sonar-web/src/main/js/app/components/nav/component/__tests__/__snapshots__/ComponentNavBreadcrumbs-test.js.snap
server/sonar-web/src/main/js/app/components/nav/component/__tests__/__snapshots__/ComponentNavMenu-test.js.snap
server/sonar-web/src/main/js/app/components/nav/global/GlobalNav.css [new file with mode: 0644]
server/sonar-web/src/main/js/app/components/nav/global/GlobalNav.js
server/sonar-web/src/main/js/app/components/nav/global/GlobalNavBranding.js
server/sonar-web/src/main/js/app/components/nav/global/GlobalNavMenu.js
server/sonar-web/src/main/js/app/components/nav/global/GlobalNavUser.js
server/sonar-web/src/main/js/app/components/nav/global/__tests__/__snapshots__/GlobalNavMenu-test.js.snap
server/sonar-web/src/main/js/app/components/nav/global/__tests__/__snapshots__/GlobalNavUser-test.js.snap
server/sonar-web/src/main/js/app/components/nav/settings/SettingsNav.js
server/sonar-web/src/main/js/app/components/nav/settings/__tests__/__snapshots__/SettingsNav-test.js.snap
server/sonar-web/src/main/js/app/components/search/Search.css [new file with mode: 0644]
server/sonar-web/src/main/js/app/components/search/Search.js
server/sonar-web/src/main/js/app/utils/startReactApp.js
server/sonar-web/src/main/js/apps/about/components/AboutApp.js
server/sonar-web/src/main/js/apps/about/components/AboutAppForSonarQubeDotCom.js
server/sonar-web/src/main/js/apps/about/components/AboutRulesForSonarQubeDotCom.js
server/sonar-web/src/main/js/apps/about/sonarqube-dot-com-styles.css
server/sonar-web/src/main/js/apps/about/styles.css
server/sonar-web/src/main/js/apps/account/account.css
server/sonar-web/src/main/js/apps/account/components/Nav.js
server/sonar-web/src/main/js/apps/component-measures/styles.css
server/sonar-web/src/main/js/apps/issues/styles.css
server/sonar-web/src/main/js/apps/organizations/navigation/OrganizationNavigation.js
server/sonar-web/src/main/js/apps/organizations/navigation/__tests__/__snapshots__/OrganizationNavigation-test.js.snap
server/sonar-web/src/main/js/components/icons-components/OrganizationIcon.js [new file with mode: 0644]
server/sonar-web/src/main/js/components/nav/ContextNavBar.css [new file with mode: 0644]
server/sonar-web/src/main/js/components/nav/ContextNavBar.js [new file with mode: 0644]
server/sonar-web/src/main/js/components/nav/NavBar.css [new file with mode: 0644]
server/sonar-web/src/main/js/components/nav/NavBar.js [new file with mode: 0644]
server/sonar-web/src/main/js/components/nav/NavBarTabs.css [new file with mode: 0644]
server/sonar-web/src/main/js/components/nav/NavBarTabs.js [new file with mode: 0644]
server/sonar-web/src/main/js/components/ui/OrganizationIcon.js [deleted file]
server/sonar-web/src/main/js/libs/third-party/bootstrap/dropdown.js
server/sonar-web/src/main/less/components/navbar.less [deleted file]
server/sonar-web/src/main/less/components/page.less
server/sonar-web/src/main/less/components/search-navigator.less
server/sonar-web/src/main/less/components/ui.less
server/sonar-web/src/main/less/print.less
server/sonar-web/src/main/less/sonar.less
server/sonar-web/src/main/less/variables.less
tests/src/test/java/org/sonarqube/pageobjects/organization/MembersPage.java
tests/src/test/java/org/sonarqube/tests/ui/OrganizationUiExtensionsTest.java
tests/src/test/java/org/sonarqube/tests/ui/UiExtensionsTest.java

index 8ddd3bcd8d45948251e32f749620aa0fbc3f31aa..f3b2803ddfa3037bd43c145f0bfc1a4cfe734ef0 100644 (file)
         <dependency>
           <groupId>com.sonarsource</groupId>
           <artifactId>sonarsource-branding</artifactId>
-          <version>1.3.0.304</version>
+          <version>1.3.0.307</version>
           <type>war</type>
           <scope>runtime</scope>
         </dependency>
index 284cba8d4360b48b3f2f02a727bedff453888d11..68c4c0f737466617a91f081d3bfa1538bee9946d 100644 (file)
@@ -28,7 +28,7 @@ export default function GlobalContainer(props: Object) {
 
   return (
     <div className="global-container">
-      <div className="page-wrapper page-wrapper-global" id="container">
+      <div className="page-wrapper" id="container">
         <div className="page-container">
           <GlobalNav location={props.location} />
           <GlobalMessagesContainer />
index 7d9396e7bf0107c20638c4515f62072d28d8d185..a2d22afea2d74cc6c3b679e4db1984e555b0522a 100644 (file)
@@ -20,6 +20,7 @@
 // @flow
 import React from 'react';
 import GlobalFooterContainer from './GlobalFooterContainer';
+import NavBar from '../../components/nav/NavBar';
 
 type Props = {
   children?: React.Element<*> | Array<React.Element<*>>,
@@ -46,10 +47,8 @@ export default class SimpleContainer extends React.PureComponent {
   render() {
     return (
       <div className="global-container">
-        <div className="page-wrapper page-wrapper-global" id="container">
-          <nav className="navbar navbar-global page-container" id="global-navigation">
-            <div className="navbar-header" />
-          </nav>
+        <div className="page-wrapper" id="container">
+          <NavBar className="navbar-global" id="global-navigation" height={30} />
 
           <div id="bd" className="page-wrapper-simple">
             <div id="nonav" className="page-simple">
diff --git a/server/sonar-web/src/main/js/app/components/nav/component/ComponentNav.css b/server/sonar-web/src/main/js/app/components/nav/component/ComponentNav.css
new file mode 100644 (file)
index 0000000..22ec0d3
--- /dev/null
@@ -0,0 +1,11 @@
+.navbar-context-favorite {
+  float: left;
+  padding: 7px 10px 0 0;
+}
+
+.navbar-context-title-qualifier {
+  display: inline-block;
+  line-height: 16px;
+  padding-top: 5px;
+  box-sizing: border-box;
+}
index 23b08126fa76d30f5381c3b0b2996a52e1399dae..d9963b913ac624fcf1bf62d12388cfb35605fb07 100644 (file)
@@ -23,9 +23,11 @@ import ComponentNavBreadcrumbs from './ComponentNavBreadcrumbs';
 import ComponentNavMeta from './ComponentNavMeta';
 import ComponentNavMenu from './ComponentNavMenu';
 import RecentHistory from '../../RecentHistory';
+import ContextNavBar from '../../../../components/nav/ContextNavBar';
 import { TooltipsContainer } from '../../../../components/mixins/tooltips-mixin';
 import { getTasksForComponent } from '../../../../api/ce';
 import { STATUSES } from '../../../../apps/background-tasks/constants';
+import './ComponentNav.css';
 
 export default class ComponentNav extends React.PureComponent {
   componentDidMount() {
@@ -66,36 +68,32 @@ export default class ComponentNav extends React.PureComponent {
 
   render() {
     return (
-      <nav className="navbar navbar-context page-container" id="context-navigation">
-        <div className="navbar-context-inner">
-          <div className="container">
-            <ComponentNavFavorite
-              component={this.props.component.key}
-              favorite={this.props.component.isFavorite}
-            />
+      <ContextNavBar id="context-navigation" height={65}>
+        <ComponentNavFavorite
+          component={this.props.component.key}
+          favorite={this.props.component.isFavorite}
+        />
 
-            <ComponentNavBreadcrumbs
-              component={this.props.component}
-              breadcrumbs={this.props.component.breadcrumbs}
-            />
+        <ComponentNavBreadcrumbs
+          component={this.props.component}
+          breadcrumbs={this.props.component.breadcrumbs}
+        />
 
-            <TooltipsContainer options={{ delay: { show: 0, hide: 2000 } }}>
-              <ComponentNavMeta
-                {...this.props}
-                {...this.state}
-                version={this.props.component.version}
-                analysisDate={this.props.component.analysisDate}
-              />
-            </TooltipsContainer>
+        <TooltipsContainer options={{ delay: { show: 0, hide: 2000 } }}>
+          <ComponentNavMeta
+            {...this.props}
+            {...this.state}
+            version={this.props.component.version}
+            analysisDate={this.props.component.analysisDate}
+          />
+        </TooltipsContainer>
 
-            <ComponentNavMenu
-              component={this.props.component}
-              conf={this.props.conf}
-              location={this.props.location}
-            />
-          </div>
-        </div>
-      </nav>
+        <ComponentNavMenu
+          component={this.props.component}
+          conf={this.props.conf}
+          location={this.props.location}
+        />
+      </ContextNavBar>
     );
   }
 }
index c719a568c701d2d5fafef8b992f22a51c2eeb225..c7f17f3a9cdac55519654ede308b1424ee9dca5a 100644 (file)
@@ -59,7 +59,7 @@ class ComponentNavBreadcrumbs extends React.PureComponent {
           <Link
             title={item.name}
             to={{ pathname: '/dashboard', query: { id: item.key } }}
-            className="link-base-color">
+            className="link-base-color link-no-underline">
             {index === breadcrumbs.length - 1
               ? <strong>
                   {itemName}
@@ -74,7 +74,7 @@ class ComponentNavBreadcrumbs extends React.PureComponent {
     });
 
     return (
-      <h2 className="navbar-context-title">
+      <h1 className="navbar-context-header">
         <OrganizationHelmet
           title={component.name}
           organization={displayOrganization ? organization : null}
@@ -84,14 +84,16 @@ class ComponentNavBreadcrumbs extends React.PureComponent {
             <span className="navbar-context-title-qualifier little-spacer-right">
               <QualifierIcon qualifier={lastItem.qualifier} />
             </span>
-            <OrganizationLink organization={organization} className="link-base-color">
+            <OrganizationLink
+              organization={organization}
+              className="link-base-color link-no-underline">
               {organization.name}
             </OrganizationLink>
             <span className="slash-separator" />
           </span>}
         {items}
         {component.visibility === 'private' && <PrivateBadge className="spacer-left" />}
-      </h2>
+      </h1>
     );
   }
 }
index 0903d35eaa9d496dc7f72aebee111565a10e7020..c484fa2b50c76920b13107c3e353fc8c2b1f4e10 100644 (file)
@@ -19,6 +19,8 @@
  */
 import React from 'react';
 import { Link } from 'react-router';
+import classNames from 'classnames';
+import NavBarTabs from '../../../../components/nav/NavBarTabs';
 import { translate } from '../../../../helpers/l10n';
 
 const SETTINGS_URLS = [
@@ -59,7 +61,7 @@ export default class ComponentNavMenu extends React.PureComponent {
     return (
       <li>
         <Link to={{ pathname, query: { id: this.props.component.key } }} activeClassName="active">
-          <i className="icon-home" />
+          {translate('overview.page')}
         </Link>
       </li>
     );
@@ -131,11 +133,10 @@ export default class ComponentNavMenu extends React.PureComponent {
     }
 
     const isSettingsActive = SETTINGS_URLS.some(url => window.location.href.indexOf(url) !== -1);
-    const className = 'dropdown' + (isSettingsActive ? ' active' : '');
     return (
-      <li className={className}>
+      <li className="dropdown">
         <a
-          className="dropdown-toggle navbar-admin-link"
+          className={classNames('dropdown-toggle', 'is-admin', { active: isSettingsActive })}
           id="component-navigation-admin"
           data-toggle="dropdown"
           href="#">
@@ -348,7 +349,7 @@ export default class ComponentNavMenu extends React.PureComponent {
 
   render() {
     return (
-      <ul className="nav navbar-nav nav-tabs">
+      <NavBarTabs>
         {this.renderDashboardLink()}
         {this.renderIssuesLink()}
         {this.renderComponentMeasuresLink()}
@@ -356,7 +357,7 @@ export default class ComponentNavMenu extends React.PureComponent {
         {this.renderActivityLink()}
         {this.renderAdministration()}
         {this.renderExtensions()}
-      </ul>
+      </NavBarTabs>
     );
   }
 }
index 385012e7de0a4e867c1208496a86b89f232fee4d..1588ae83e8a60adec5617334b22f1b872b7c1fc9 100644 (file)
@@ -1,8 +1,8 @@
 // Jest Snapshot v1, https://goo.gl/fbAQLP
 
 exports[`should not render breadcrumbs with one element 1`] = `
-<h2
-  className="navbar-context-title"
+<h1
+  className="navbar-context-header"
 >
   <OrganizationHelmet
     organization={null}
@@ -17,7 +17,7 @@ exports[`should not render breadcrumbs with one element 1`] = `
       />
     </span>
     <Link
-      className="link-base-color"
+      className="link-base-color link-no-underline"
       onlyActiveOnIndex={false}
       style={Object {}}
       title="My Project"
@@ -35,12 +35,12 @@ exports[`should not render breadcrumbs with one element 1`] = `
       </strong>
     </Link>
   </span>
-</h2>
+</h1>
 `;
 
 exports[`should render organization 1`] = `
-<h2
-  className="navbar-context-title"
+<h1
+  className="navbar-context-header"
 >
   <OrganizationHelmet
     organization={
@@ -60,7 +60,7 @@ exports[`should render organization 1`] = `
       />
     </span>
     <OrganizationLink
-      className="link-base-color"
+      className="link-base-color link-no-underline"
       organization={
         Object {
           "key": "foo",
@@ -76,7 +76,7 @@ exports[`should render organization 1`] = `
   </span>
   <span>
     <Link
-      className="link-base-color"
+      className="link-base-color link-no-underline"
       onlyActiveOnIndex={false}
       style={Object {}}
       title="My Project"
@@ -94,5 +94,5 @@ exports[`should render organization 1`] = `
       </strong>
     </Link>
   </span>
-</h2>
+</h1>
 `;
index 9b9a24ab6fe07e7655d262e9b957fbdd54b1152c..1772a834780be3a14ec60ede760d39492af132db 100644 (file)
@@ -1,9 +1,7 @@
 // Jest Snapshot v1, https://goo.gl/fbAQLP
 
 exports[`should work with extensions 1`] = `
-<ul
-  className="nav navbar-nav nav-tabs"
->
+<NavBarTabs>
   <li>
     <Link
       activeClassName="active"
@@ -18,9 +16,7 @@ exports[`should work with extensions 1`] = `
         }
       }
     >
-      <i
-        className="icon-home"
-      />
+      overview.page
     </Link>
   </li>
   <li>
@@ -96,7 +92,7 @@ exports[`should work with extensions 1`] = `
     className="dropdown"
   >
     <a
-      className="dropdown-toggle navbar-admin-link"
+      className="dropdown-toggle is-admin"
       data-toggle="dropdown"
       href="#"
       id="component-navigation-admin"
@@ -200,13 +196,11 @@ exports[`should work with extensions 1`] = `
       </li>
     </ul>
   </li>
-</ul>
+</NavBarTabs>
 `;
 
 exports[`should work with multiple extensions 1`] = `
-<ul
-  className="nav navbar-nav nav-tabs"
->
+<NavBarTabs>
   <li>
     <Link
       activeClassName="active"
@@ -221,9 +215,7 @@ exports[`should work with multiple extensions 1`] = `
         }
       }
     >
-      <i
-        className="icon-home"
-      />
+      overview.page
     </Link>
   </li>
   <li>
@@ -299,7 +291,7 @@ exports[`should work with multiple extensions 1`] = `
     className="dropdown"
   >
     <a
-      className="dropdown-toggle navbar-admin-link"
+      className="dropdown-toggle is-admin"
       data-toggle="dropdown"
       href="#"
       id="component-navigation-admin"
@@ -437,5 +429,5 @@ exports[`should work with multiple extensions 1`] = `
       </li>
     </ul>
   </li>
-</ul>
+</NavBarTabs>
 `;
diff --git a/server/sonar-web/src/main/js/app/components/nav/global/GlobalNav.css b/server/sonar-web/src/main/js/app/components/nav/global/GlobalNav.css
new file mode 100644 (file)
index 0000000..bdb8e01
--- /dev/null
@@ -0,0 +1,67 @@
+.navbar-global,
+.navbar-global .navbar-inner {
+  background-color: #262626;
+  z-index: 421;
+}
+
+.navbar-brand {
+  display: block;
+  margin-left: -10px;
+  padding-left: 10px;
+  padding-right: 10px;
+  border: none;
+}
+
+.navbar-brand:hover,
+.navbar-brand:focus {
+  background-color: #000;
+}
+
+.navbar-login {
+  margin-right: -10px;
+}
+
+.navbar-avatar {
+  margin-right: -3px !important;
+  padding: 3px !important;
+}
+
+.navbar-help {
+  line-height: 16px !important;
+  padding: 7px !important;
+}
+
+.global-navbar-menu {
+  display: flex;
+  align-items: center;
+}
+
+.global-navbar-menu > li > a {
+  display: block;
+  padding: 8px 10px;
+  line-height: 14px;
+  border: none;
+  color: #ccc;
+  font-size: 12px;
+  letter-spacing: 0.05em;
+  transition: none;
+}
+
+.global-navbar-menu > li > a.active,
+.global-navbar-menu > li > a:hover,
+.global-navbar-menu > li > a:focus {
+  background-color: #4b9fd5;
+  color: #fff;
+}
+
+.global-navbar-menu > li > a.is-admin.active,
+.global-navbar-menu > li > a.is-admin:hover,
+.global-navbar-menu > li > a.is-admin:focus {
+  background-color: #ed7d20;
+}
+
+@media print {
+  .navbar-global {
+    display: none !important;
+  }
+}
index 5f6de29a8f78273726fec9e0b538e664ea671f87..5ad2c836f371da69dc87bcac6e1f74b4217036a1 100644 (file)
@@ -25,11 +25,13 @@ import GlobalNavMenu from './GlobalNavMenu';
 import GlobalNavUserContainer from './GlobalNavUserContainer';
 import Search from '../../search/Search';
 import GlobalHelp from '../../help/GlobalHelp';
+import NavBar from '../../../../components/nav/NavBar';
 import Tooltip from '../../../../components/controls/Tooltip';
 import HelpIcon from '../../../../components/icons-components/HelpIcon';
 import OnboardingModal from '../../../../apps/tutorials/onboarding/OnboardingModal';
 import { getCurrentUser, getAppState, getSettingValue } from '../../../../store/rootReducer';
 import { translate } from '../../../../helpers/l10n';
+import './GlobalNav.css';
 
 type Props = {
   appState: { organizationsEnabled: boolean },
@@ -96,29 +98,27 @@ class GlobalNav extends React.PureComponent {
 
   render() {
     return (
-      <nav className="navbar navbar-global page-container" id="global-navigation">
-        <div className="container">
-          <GlobalNavBranding />
-
-          <GlobalNavMenu {...this.props} />
-
-          <ul className="nav navbar-nav navbar-right">
-            <Search appState={this.props.appState} currentUser={this.props.currentUser} />
-            <li>
-              <a className="navbar-help" onClick={this.handleHelpClick} href="#">
-                {this.state.onboardingTutorialTooltip
-                  ? <Tooltip
-                      defaultVisible={true}
-                      overlay={translate('tutorials.follow_later')}
-                      trigger="manual">
-                      <HelpIcon />
-                    </Tooltip>
-                  : <HelpIcon />}
-              </a>
-            </li>
-            <GlobalNavUserContainer {...this.props} />
-          </ul>
-        </div>
+      <NavBar className="navbar-global" id="global-navigation" height={30}>
+        <GlobalNavBranding />
+
+        <GlobalNavMenu {...this.props} />
+
+        <ul className="global-navbar-menu pull-right">
+          <Search appState={this.props.appState} currentUser={this.props.currentUser} />
+          <li>
+            <a className="navbar-help" onClick={this.handleHelpClick} href="#">
+              {this.state.onboardingTutorialTooltip
+                ? <Tooltip
+                    defaultVisible={true}
+                    overlay={translate('tutorials.follow_later')}
+                    trigger="manual">
+                    <HelpIcon />
+                  </Tooltip>
+                : <HelpIcon />}
+            </a>
+          </li>
+          <GlobalNavUserContainer {...this.props} />
+        </ul>
 
         {this.state.helpOpen &&
           <GlobalHelp
@@ -130,7 +130,7 @@ class GlobalNav extends React.PureComponent {
 
         {this.state.onboardingTutorialOpen &&
           <OnboardingModal onFinish={this.closeOnboardingTutorial} />}
-      </nav>
+      </NavBar>
     );
   }
 }
index d0bac2720ea5fe734bb67e0d186025cf7efd94f5..968a9d109eb9937c62e7843759f301c2cf1de4ce 100644 (file)
@@ -31,7 +31,7 @@ class GlobalNavBranding extends React.PureComponent {
 
   renderLogo() {
     const url = this.props.customLogoUrl || `${window.baseUrl}/images/logo.svg`;
-    const width = this.props.customLogoWidth || 100;
+    const width = this.props.customLogoUrl ? this.props.customLogoWidth || 100 : 83;
     const height = 30;
     const title = translate('layout.sonar.slogan');
     return <img src={url} width={width} height={height} alt={title} title={title} />;
@@ -39,11 +39,9 @@ class GlobalNavBranding extends React.PureComponent {
 
   render() {
     const homeController = this.props.currentUser.isLoggedIn ? '/projects' : '/about';
-    const homeLinkClassName =
-      'navbar-brand' + (this.props.customLogoUrl ? ' navbar-brand-custom' : '');
     return (
-      <div className="navbar-header">
-        <Link to={homeController} className={homeLinkClassName}>
+      <div className="pull-left">
+        <Link to={homeController} className="navbar-brand">
           {this.renderLogo()}
         </Link>
       </div>
index 5b99dd06c9282d33668fe8f7979e65f0659a2003..6535201176f21c0c952860b944248c40309e4400 100644 (file)
@@ -111,7 +111,7 @@ export default class GlobalNavMenu extends React.PureComponent {
     }
     return (
       <li>
-        <Link to="/settings" className="navbar-admin-link" activeClassName="active">
+        <Link to="/settings" className="is-admin" activeClassName="active">
           {translate('layout.settings')}
         </Link>
       </li>
@@ -152,7 +152,7 @@ export default class GlobalNavMenu extends React.PureComponent {
     const { organizationsEnabled } = this.props.appState;
 
     return (
-      <ul className="nav navbar-nav">
+      <ul className="global-navbar-menu pull-left">
         {this.renderProjects()}
         {governanceInstalled && this.renderPortfolios()}
         {this.renderIssuesLink()}
index d5d25ec79a6d8d9ec2ef5df935d5c5717cc4d75e..830a351b05e1a36a9f3701558221580761751c29 100644 (file)
@@ -168,7 +168,7 @@ export default class GlobalNavUser extends React.PureComponent {
   renderAnonymous() {
     return (
       <li>
-        <a onClick={this.handleLogin} href="#">
+        <a className="navbar-login" onClick={this.handleLogin} href="#">
           {translate('layout.login')}
         </a>
       </li>
index bb21d44b23e5387d17b47c86a9459ced8b3576a2..3315afa83e213930824a32a4163178dbca2d36cd 100644 (file)
@@ -2,7 +2,7 @@
 
 exports[`should show administration menu if the user has the rights 1`] = `
 <ul
-  className="nav navbar-nav"
+  className="global-navbar-menu pull-left"
 >
   <li>
     <Link
@@ -63,7 +63,7 @@ exports[`should show administration menu if the user has the rights 1`] = `
   <li>
     <Link
       activeClassName="active"
-      className="navbar-admin-link"
+      className="is-admin"
       onlyActiveOnIndex={false}
       style={Object {}}
       to="/settings"
@@ -76,7 +76,7 @@ exports[`should show administration menu if the user has the rights 1`] = `
 
 exports[`should work with extensions 1`] = `
 <ul
-  className="nav navbar-nav"
+  className="global-navbar-menu pull-left"
 >
   <li>
     <Link
index f3800e5f3ece72b10e9e3dd61931c335bcc16c22..f42167519ef26df98e152ef5aa1b530b39eea3f1 100644 (file)
@@ -64,6 +64,7 @@ exports[`should not render the users organizations when they are not activated 1
 exports[`should render the right interface for anonymous user 1`] = `
 <li>
   <a
+    className="navbar-login"
     href="#"
     onClick={[Function]}
   >
@@ -322,6 +323,7 @@ exports[`should update the component correctly when the user changes to anonymou
 exports[`should update the component correctly when the user changes to anonymous 2`] = `
 <li>
   <a
+    className="navbar-login"
     href="#"
     onClick={[Function]}
   >
index 88750547c4a190dda4c4f538021e2ddc4fb218f6..21540b25a997864db0caf2323ea377e735efba97 100644 (file)
@@ -21,6 +21,8 @@ import React from 'react';
 import classNames from 'classnames';
 import { IndexLink, Link } from 'react-router';
 import { connect } from 'react-redux';
+import ContextNavBar from '../../../../components/nav/ContextNavBar';
+import NavBarTabs from '../../../../components/nav/NavBarTabs';
 import { translate } from '../../../../helpers/l10n';
 import { areThereCustomOrganizations } from '../../../../store/rootReducer';
 
@@ -64,135 +66,129 @@ class SettingsNav extends React.PureComponent {
     const isProjects = this.isProjectsActive();
     const isSystem = this.isSystemActive();
 
-    const securityClassName = classNames('dropdown', { active: isSecurity });
-    const projectsClassName = classNames('dropdown', { active: isProjects });
-    const systemClassName = classNames('dropdown', { active: isSystem });
-    const configurationClassNames = classNames('dropdown', {
+    const securityClassName = classNames('dropdown-toggle', { active: isSecurity });
+    const projectsClassName = classNames('dropdown-toggle', { active: isProjects });
+    const systemClassName = classNames('dropdown-toggle', { active: isSystem });
+    const configurationClassNames = classNames('dropdown-toggle', {
       active: !isSecurity && !isProjects && !isSystem
     });
 
     return (
-      <nav className="navbar navbar-context page-container" id="context-navigation">
-        <div className="navbar-context-inner">
-          <div className="container">
-            <ul className="nav navbar-nav nav-crumbs">
+      <ContextNavBar id="context-navigation" height={65}>
+        <h1 className="navbar-context-header">
+          <strong>
+            {translate('layout.settings')}
+          </strong>
+        </h1>
+
+        <NavBarTabs>
+          <li className="dropdown">
+            <a
+              className={configurationClassNames}
+              data-toggle="dropdown"
+              id="settings-navigation-configuration"
+              href="#">
+              {translate('sidebar.project_settings')} <i className="icon-dropdown" />
+            </a>
+            <ul className="dropdown-menu">
               <li>
-                <IndexLink to="/settings">
-                  {translate('layout.settings')}
+                <IndexLink to="/settings" activeClassName="active">
+                  {translate('settings.page')}
                 </IndexLink>
               </li>
+              <li>
+                <IndexLink to="/settings/licenses" activeClassName="active">
+                  {translate('property.category.licenses')}
+                </IndexLink>
+              </li>
+              <li>
+                <IndexLink to="/settings/encryption" activeClassName="active">
+                  {translate('property.category.security.encryption')}
+                </IndexLink>
+              </li>
+              <li>
+                <IndexLink to="/settings/server_id" activeClassName="active">
+                  {translate('property.category.server_id')}
+                </IndexLink>
+              </li>
+              <li>
+                <IndexLink to="/metrics" activeClassName="active">
+                  Custom Metrics
+                </IndexLink>
+              </li>
+              {this.props.extensions.map(this.renderExtension)}
             </ul>
+          </li>
 
-            <ul className="nav navbar-nav nav-tabs">
-              <li className={configurationClassNames}>
-                <a
-                  className="dropdown-toggle"
-                  data-toggle="dropdown"
-                  id="settings-navigation-configuration"
-                  href="#">
-                  {translate('sidebar.project_settings')} <i className="icon-dropdown" />
-                </a>
-                <ul className="dropdown-menu">
-                  <li>
-                    <IndexLink to="/settings" activeClassName="active">
-                      {translate('settings.page')}
-                    </IndexLink>
-                  </li>
-                  <li>
-                    <IndexLink to="/settings/licenses" activeClassName="active">
-                      {translate('property.category.licenses')}
-                    </IndexLink>
-                  </li>
-                  <li>
-                    <IndexLink to="/settings/encryption" activeClassName="active">
-                      {translate('property.category.security.encryption')}
-                    </IndexLink>
-                  </li>
-                  <li>
-                    <IndexLink to="/settings/server_id" activeClassName="active">
-                      {translate('property.category.server_id')}
-                    </IndexLink>
-                  </li>
-                  <li>
-                    <IndexLink to="/metrics" activeClassName="active">
-                      Custom Metrics
-                    </IndexLink>
-                  </li>
-                  {this.props.extensions.map(this.renderExtension)}
-                </ul>
+          <li className="dropdown">
+            <a className={securityClassName} data-toggle="dropdown" href="#">
+              {translate('sidebar.security')} <i className="icon-dropdown" />
+            </a>
+            <ul className="dropdown-menu">
+              <li>
+                <IndexLink to="/users" activeClassName="active">
+                  {translate('users.page')}
+                </IndexLink>
               </li>
-
-              <li className={securityClassName}>
-                <a className="dropdown-toggle" data-toggle="dropdown" href="#">
-                  {translate('sidebar.security')} <i className="icon-dropdown" />
-                </a>
-                <ul className="dropdown-menu">
-                  <li>
-                    <IndexLink to="/users" activeClassName="active">
-                      {translate('users.page')}
-                    </IndexLink>
-                  </li>
-                  {!this.props.customOrganizations &&
-                    <li>
-                      <IndexLink to="/groups" activeClassName="active">
-                        {translate('user_groups.page')}
-                      </IndexLink>
-                    </li>}
-                  {!this.props.customOrganizations &&
-                    <li>
-                      <IndexLink to="/roles/global" activeClassName="active">
-                        {translate('global_permissions.page')}
-                      </IndexLink>
-                    </li>}
-                  {!this.props.customOrganizations &&
-                    <li>
-                      <IndexLink to="/permission_templates" activeClassName="active">
-                        {translate('permission_templates')}
-                      </IndexLink>
-                    </li>}
-                </ul>
+              {!this.props.customOrganizations &&
+                <li>
+                  <IndexLink to="/groups" activeClassName="active">
+                    {translate('user_groups.page')}
+                  </IndexLink>
+                </li>}
+              {!this.props.customOrganizations &&
+                <li>
+                  <IndexLink to="/roles/global" activeClassName="active">
+                    {translate('global_permissions.page')}
+                  </IndexLink>
+                </li>}
+              {!this.props.customOrganizations &&
+                <li>
+                  <IndexLink to="/permission_templates" activeClassName="active">
+                    {translate('permission_templates')}
+                  </IndexLink>
+                </li>}
+            </ul>
+          </li>
+
+          <li className="dropdown">
+            <a className={projectsClassName} data-toggle="dropdown" href="#">
+              {translate('sidebar.projects')} <i className="icon-dropdown" />
+            </a>
+            <ul className="dropdown-menu">
+              {!this.props.customOrganizations &&
+                <li>
+                  <IndexLink to="/projects_admin" activeClassName="active">
+                    Management
+                  </IndexLink>
+                </li>}
+              <li>
+                <IndexLink to="/background_tasks" activeClassName="active">
+                  {translate('background_tasks.page')}
+                </IndexLink>
               </li>
+            </ul>
+          </li>
 
-              <li className={projectsClassName}>
-                <a className="dropdown-toggle" data-toggle="dropdown" href="#">
-                  {translate('sidebar.projects')} <i className="icon-dropdown" />
-                </a>
-                <ul className="dropdown-menu">
-                  {!this.props.customOrganizations &&
-                    <li>
-                      <IndexLink to="/projects_admin" activeClassName="active">
-                        Management
-                      </IndexLink>
-                    </li>}
-                  <li>
-                    <IndexLink to="/background_tasks" activeClassName="active">
-                      {translate('background_tasks.page')}
-                    </IndexLink>
-                  </li>
-                </ul>
+          <li className="dropdown">
+            <a className={systemClassName} data-toggle="dropdown" href="#">
+              {translate('sidebar.system')} <i className="icon-dropdown" />
+            </a>
+            <ul className="dropdown-menu">
+              <li>
+                <IndexLink to="/updatecenter" activeClassName="active">
+                  {translate('update_center.page')}
+                </IndexLink>
               </li>
-
-              <li className={systemClassName}>
-                <a className="dropdown-toggle" data-toggle="dropdown" href="#">
-                  {translate('sidebar.system')} <i className="icon-dropdown" />
-                </a>
-                <ul className="dropdown-menu">
-                  <li>
-                    <IndexLink to="/updatecenter" activeClassName="active">
-                      {translate('update_center.page')}
-                    </IndexLink>
-                  </li>
-                  <li>
-                    <IndexLink to="/system" activeClassName="active">
-                      {translate('system_info.page')}
-                    </IndexLink>
-                  </li>
-                </ul>
+              <li>
+                <IndexLink to="/system" activeClassName="active">
+                  {translate('system_info.page')}
+                </IndexLink>
               </li>
             </ul>
-          </div>
-        </div>
-      </nav>
+          </li>
+        </NavBarTabs>
+      </ContextNavBar>
     );
   }
 }
index 1efd658114f2de96bd9cb2bb7337edf9685584d5..7f285d4906cef782cbd6d1c3804177b4d65130ff 100644 (file)
 // Jest Snapshot v1, https://goo.gl/fbAQLP
 
 exports[`should work with extensions 1`] = `
-<nav
-  className="navbar navbar-context page-container"
+<ContextNavBar
+  height={65}
   id="context-navigation"
 >
-  <div
-    className="navbar-context-inner"
+  <h1
+    className="navbar-context-header"
   >
-    <div
-      className="container"
+    <strong>
+      layout.settings
+    </strong>
+  </h1>
+  <NavBarTabs>
+    <li
+      className="dropdown"
     >
+      <a
+        className="dropdown-toggle active"
+        data-toggle="dropdown"
+        href="#"
+        id="settings-navigation-configuration"
+      >
+        sidebar.project_settings
+         
+        <i
+          className="icon-dropdown"
+        />
+      </a>
       <ul
-        className="nav navbar-nav nav-crumbs"
+        className="dropdown-menu"
       >
         <li>
           <IndexLink
+            activeClassName="active"
             to="/settings"
           >
-            layout.settings
+            settings.page
+          </IndexLink>
+        </li>
+        <li>
+          <IndexLink
+            activeClassName="active"
+            to="/settings/licenses"
+          >
+            property.category.licenses
+          </IndexLink>
+        </li>
+        <li>
+          <IndexLink
+            activeClassName="active"
+            to="/settings/encryption"
+          >
+            property.category.security.encryption
+          </IndexLink>
+        </li>
+        <li>
+          <IndexLink
+            activeClassName="active"
+            to="/settings/server_id"
+          >
+            property.category.server_id
           </IndexLink>
         </li>
+        <li>
+          <IndexLink
+            activeClassName="active"
+            to="/metrics"
+          >
+            Custom Metrics
+          </IndexLink>
+        </li>
+        <li>
+          <Link
+            activeClassName="active"
+            onlyActiveOnIndex={false}
+            style={Object {}}
+            to="/admin/extension/foo"
+          >
+            Foo
+          </Link>
+        </li>
       </ul>
+    </li>
+    <li
+      className="dropdown"
+    >
+      <a
+        className="dropdown-toggle"
+        data-toggle="dropdown"
+        href="#"
+      >
+        sidebar.security
+         
+        <i
+          className="icon-dropdown"
+        />
+      </a>
       <ul
-        className="nav navbar-nav nav-tabs"
+        className="dropdown-menu"
       >
-        <li
-          className="dropdown active"
-        >
-          <a
-            className="dropdown-toggle"
-            data-toggle="dropdown"
-            href="#"
-            id="settings-navigation-configuration"
+        <li>
+          <IndexLink
+            activeClassName="active"
+            to="/users"
           >
-            sidebar.project_settings
-             
-            <i
-              className="icon-dropdown"
-            />
-          </a>
-          <ul
-            className="dropdown-menu"
+            users.page
+          </IndexLink>
+        </li>
+        <li>
+          <IndexLink
+            activeClassName="active"
+            to="/groups"
           >
-            <li>
-              <IndexLink
-                activeClassName="active"
-                to="/settings"
-              >
-                settings.page
-              </IndexLink>
-            </li>
-            <li>
-              <IndexLink
-                activeClassName="active"
-                to="/settings/licenses"
-              >
-                property.category.licenses
-              </IndexLink>
-            </li>
-            <li>
-              <IndexLink
-                activeClassName="active"
-                to="/settings/encryption"
-              >
-                property.category.security.encryption
-              </IndexLink>
-            </li>
-            <li>
-              <IndexLink
-                activeClassName="active"
-                to="/settings/server_id"
-              >
-                property.category.server_id
-              </IndexLink>
-            </li>
-            <li>
-              <IndexLink
-                activeClassName="active"
-                to="/metrics"
-              >
-                Custom Metrics
-              </IndexLink>
-            </li>
-            <li>
-              <Link
-                activeClassName="active"
-                onlyActiveOnIndex={false}
-                style={Object {}}
-                to="/admin/extension/foo"
-              >
-                Foo
-              </Link>
-            </li>
-          </ul>
+            user_groups.page
+          </IndexLink>
         </li>
-        <li
-          className="dropdown"
-        >
-          <a
-            className="dropdown-toggle"
-            data-toggle="dropdown"
-            href="#"
+        <li>
+          <IndexLink
+            activeClassName="active"
+            to="/roles/global"
           >
-            sidebar.security
-             
-            <i
-              className="icon-dropdown"
-            />
-          </a>
-          <ul
-            className="dropdown-menu"
+            global_permissions.page
+          </IndexLink>
+        </li>
+        <li>
+          <IndexLink
+            activeClassName="active"
+            to="/permission_templates"
           >
-            <li>
-              <IndexLink
-                activeClassName="active"
-                to="/users"
-              >
-                users.page
-              </IndexLink>
-            </li>
-            <li>
-              <IndexLink
-                activeClassName="active"
-                to="/groups"
-              >
-                user_groups.page
-              </IndexLink>
-            </li>
-            <li>
-              <IndexLink
-                activeClassName="active"
-                to="/roles/global"
-              >
-                global_permissions.page
-              </IndexLink>
-            </li>
-            <li>
-              <IndexLink
-                activeClassName="active"
-                to="/permission_templates"
-              >
-                permission_templates
-              </IndexLink>
-            </li>
-          </ul>
+            permission_templates
+          </IndexLink>
         </li>
-        <li
-          className="dropdown"
-        >
-          <a
-            className="dropdown-toggle"
-            data-toggle="dropdown"
-            href="#"
+      </ul>
+    </li>
+    <li
+      className="dropdown"
+    >
+      <a
+        className="dropdown-toggle"
+        data-toggle="dropdown"
+        href="#"
+      >
+        sidebar.projects
+         
+        <i
+          className="icon-dropdown"
+        />
+      </a>
+      <ul
+        className="dropdown-menu"
+      >
+        <li>
+          <IndexLink
+            activeClassName="active"
+            to="/projects_admin"
           >
-            sidebar.projects
-             
-            <i
-              className="icon-dropdown"
-            />
-          </a>
-          <ul
-            className="dropdown-menu"
+            Management
+          </IndexLink>
+        </li>
+        <li>
+          <IndexLink
+            activeClassName="active"
+            to="/background_tasks"
           >
-            <li>
-              <IndexLink
-                activeClassName="active"
-                to="/projects_admin"
-              >
-                Management
-              </IndexLink>
-            </li>
-            <li>
-              <IndexLink
-                activeClassName="active"
-                to="/background_tasks"
-              >
-                background_tasks.page
-              </IndexLink>
-            </li>
-          </ul>
+            background_tasks.page
+          </IndexLink>
         </li>
-        <li
-          className="dropdown"
-        >
-          <a
-            className="dropdown-toggle"
-            data-toggle="dropdown"
-            href="#"
+      </ul>
+    </li>
+    <li
+      className="dropdown"
+    >
+      <a
+        className="dropdown-toggle"
+        data-toggle="dropdown"
+        href="#"
+      >
+        sidebar.system
+         
+        <i
+          className="icon-dropdown"
+        />
+      </a>
+      <ul
+        className="dropdown-menu"
+      >
+        <li>
+          <IndexLink
+            activeClassName="active"
+            to="/updatecenter"
           >
-            sidebar.system
-             
-            <i
-              className="icon-dropdown"
-            />
-          </a>
-          <ul
-            className="dropdown-menu"
+            update_center.page
+          </IndexLink>
+        </li>
+        <li>
+          <IndexLink
+            activeClassName="active"
+            to="/system"
           >
-            <li>
-              <IndexLink
-                activeClassName="active"
-                to="/updatecenter"
-              >
-                update_center.page
-              </IndexLink>
-            </li>
-            <li>
-              <IndexLink
-                activeClassName="active"
-                to="/system"
-              >
-                system_info.page
-              </IndexLink>
-            </li>
-          </ul>
+            system_info.page
+          </IndexLink>
         </li>
       </ul>
-    </div>
-  </div>
-</nav>
+    </li>
+  </NavBarTabs>
+</ContextNavBar>
 `;
diff --git a/server/sonar-web/src/main/js/app/components/search/Search.css b/server/sonar-web/src/main/js/app/components/search/Search.css
new file mode 100644 (file)
index 0000000..f9297ea
--- /dev/null
@@ -0,0 +1,97 @@
+.navbar-search {
+  position: relative;
+  padding-right: 3px;
+}
+
+.navbar-search-input {
+  vertical-align: middle;
+  width: 310px;
+  margin-top: 3px;
+  margin-bottom: 3px;
+  padding-left: 26px !important;
+}
+
+.navbar-search-input-hint {
+  position: absolute;
+  top: 4px;
+  right: 30px;
+  line-height: 24px;
+  font-size: 12px;
+  color: #777;
+}
+.navbar-search-input-hint.is-shifted {
+  z-index: 7501;
+  top: 32px;
+}
+
+.navbar-search-icon {
+  position: relative;
+  vertical-align: middle;
+  width: 16px;
+  margin-right: -20px;
+  color: #777;
+}
+
+.navbar-search-icon:before {
+  font-size: 14px;
+}
+
+.navbar-search-item-link {
+  display: flex !important;
+}
+
+.navbar-search-item-match {
+  flex-grow: 5;
+  overflow: hidden;
+  text-overflow: ellipsis;
+}
+
+.navbar-search-item-right {
+  flex-grow: 1;
+  padding-left: 10px;
+  text-align: right;
+}
+
+.navbar-search-item-icons {
+  position: relative;
+  flex-shrink: 0;
+  width: 16px;
+  height: 16px;
+}
+.navbar-search-item-icons > * {
+  position: absolute;
+  z-index: 5;
+  top: 0;
+  left: 0;
+}
+
+.navbar-search-item-icons > .icon-star,
+.navbar-search-item-icons > .icon-clock {
+  z-index: 6;
+  top: -4px;
+  left: -5px;
+}
+
+.navbar-search-shortcut-hint {
+  line-height: 16px;
+  margin-top: 5px;
+  padding: 5px 10px;
+  border-top: 1px solid #e6e6e6;
+  background-color: #f3f3f3;
+  color: #777;
+  font-size: 11px;
+}
+
+.navbar-search-no-results {
+  margin-top: 4px;
+  padding: 5px 10px;
+}
+
+.global-navbar-search-dropdown {
+  max-height: 80vh;
+  width: 440px;
+  padding: 0;
+  overflow-y: auto;
+  overflow-x: hidden;
+  box-shadow: 0 6px 12px rgba(0, 0, 0, .175);
+}
index 040986681419b27938327813038b72d8dbb8edcd..808614922d1ec4336dd2d2a627f8a1336c2f64dc 100644 (file)
@@ -33,6 +33,7 @@ import { getSuggestions } from '../../../api/components';
 import { translate, translateWithParameters } from '../../../helpers/l10n';
 import { scrollToElement } from '../../../helpers/scrolling';
 import { getProjectUrl } from '../../../helpers/urls';
+import './Search.css';
 
 type Props = {|
   appState: { organizationsEnabled: boolean },
index 18f4ba69ed7a99bf04fb783a3cc257d5b9411711..41779d0b4ab6015860b9cc20be322ff4e456dde7 100644 (file)
@@ -29,7 +29,6 @@ import GlobalContainer from '../components/GlobalContainer';
 import SimpleContainer from '../components/SimpleContainer';
 import SimpleSessionsContainer from '../../apps/sessions/components/SimpleSessionsContainer';
 import Landing from '../components/Landing';
-import ProjectContainer from '../components/ProjectContainer';
 import ProjectAdminContainer from '../components/ProjectAdminContainer';
 import ProjectPageExtension from '../components/extensions/ProjectPageExtension';
 import ProjectAdminPageExtension from '../components/extensions/ProjectAdminPageExtension';
@@ -165,7 +164,9 @@ const startReactApp = () => {
                   <Route path="profiles" childRoutes={qualityProfilesRoutes} />
                   <Route path="web_api" childRoutes={webAPIRoutes} />
 
-                  <Route component={ProjectContainer}>
+                  <Route
+                    getComponent={() =>
+                      import('../components/ProjectContainer').then(i => i.default)}>
                     <Route path="code" childRoutes={codeRoutes} />
                     <Route path="component_measures" childRoutes={componentMeasuresRoutes} />
                     <Route path="custom_measures" childRoutes={customMeasuresRoutes} />
index f22509ca1d581545b09c52bbcab4a32731b63713..715543e99a4ee67ec5efeb04eb43164af72b1b5a 100644 (file)
@@ -132,67 +132,65 @@ class AboutApp extends React.PureComponent {
     }
 
     return (
-      <div id="about-page" className="about-page">
-        <div className="about-page-container">
-          <div className="about-page-entry">
-            <div className="about-page-intro">
-              <h1 className="big-spacer-bottom">
-                {translate('layout.sonar.slogan')}
-              </h1>
-              {!this.props.currentUser.isLoggedIn &&
-                <Link to="/sessions/new" className="button button-active big-spacer-right">
-                  {translate('layout.login')}
-                </Link>}
-              <a
-                className="button"
-                href="https://redirect.sonarsource.com/doc/home.html"
-                target="_blank">
-                {translate('about_page.read_documentation')}
-              </a>
-            </div>
-
-            <div className="about-page-instance">
-              <AboutProjects count={projectsCount} loading={loading} />
-              <EntryIssueTypes
-                bugs={bugs}
-                codeSmells={codeSmells}
-                loading={loading}
-                vulnerabilities={vulnerabilities}
-              />
-            </div>
+      <div id="about-page" className="page page-limited about-page">
+        <div className="about-page-entry">
+          <div className="about-page-intro">
+            <h1 className="big-spacer-bottom">
+              {translate('layout.sonar.slogan')}
+            </h1>
+            {!this.props.currentUser.isLoggedIn &&
+              <Link to="/sessions/new" className="button button-active big-spacer-right">
+                {translate('layout.login')}
+              </Link>}
+            <a
+              className="button"
+              href="https://redirect.sonarsource.com/doc/home.html"
+              target="_blank">
+              {translate('about_page.read_documentation')}
+            </a>
           </div>
 
-          {customText != null &&
-            customText.value &&
-            <div
-              className="about-page-section"
-              dangerouslySetInnerHTML={{ __html: customText.value }}
-            />}
+          <div className="about-page-instance">
+            <AboutProjects count={projectsCount} loading={loading} />
+            <EntryIssueTypes
+              bugs={bugs}
+              codeSmells={codeSmells}
+              loading={loading}
+              vulnerabilities={vulnerabilities}
+            />
+          </div>
+        </div>
 
-          <AboutLanguages />
+        {customText != null &&
+          customText.value &&
+          <div
+            className="about-page-section"
+            dangerouslySetInnerHTML={{ __html: customText.value }}
+          />}
 
-          <AboutQualityModel />
+        <AboutLanguages />
 
-          <div className="flex-columns">
-            <div className="flex-column flex-column-half about-page-group-boxes">
-              <AboutCleanCode />
-            </div>
-            <div className="flex-column flex-column-half about-page-group-boxes">
-              <AboutLeakPeriod />
-            </div>
-          </div>
+        <AboutQualityModel />
 
-          <div className="flex-columns">
-            <div className="flex-column flex-column-half about-page-group-boxes">
-              <AboutQualityGates />
-            </div>
-            <div className="flex-column flex-column-half about-page-group-boxes">
-              <AboutStandards appState={this.props.appState} />
-            </div>
+        <div className="flex-columns">
+          <div className="flex-column flex-column-half about-page-group-boxes">
+            <AboutCleanCode />
+          </div>
+          <div className="flex-column flex-column-half about-page-group-boxes">
+            <AboutLeakPeriod />
           </div>
+        </div>
 
-          <AboutScanners />
+        <div className="flex-columns">
+          <div className="flex-column flex-column-half about-page-group-boxes">
+            <AboutQualityGates />
+          </div>
+          <div className="flex-column flex-column-half about-page-group-boxes">
+            <AboutStandards appState={this.props.appState} />
+          </div>
         </div>
+
+        <AboutScanners />
       </div>
     );
   }
index 2e9eee74ed4e21acbd08132bb8aa1cb0ac10522b..80041d540bbab0dd4527202dac908a74d950839a 100644 (file)
@@ -51,7 +51,7 @@ export default function AboutAppForSonarQubeDotCom(props: Props) {
   return (
     <div id="about-page" className="about-page sqcom-about-page">
       <div className="sqcom-about-page-entry">
-        <div className="about-page-container">
+        <div className="page-limited">
           <div className="sqcom-about-page-intro">
             <h1 className="big-spacer-bottom">
               Continuous Code Quality<br />as a Service
@@ -73,7 +73,7 @@ export default function AboutAppForSonarQubeDotCom(props: Props) {
 
       <AboutRulesForSonarQubeDotCom appState={props.appState} />
 
-      <div className="about-page-container">
+      <div className="page-limited">
         {customText != null &&
           customText.value &&
           <div
index 5add8a0eab14255cd0d6d174889253f08c3634a5..3496a27e3d39eccee4a5ec16e117ae434a8e231e 100644 (file)
@@ -34,7 +34,7 @@ export default function AboutRulesForSonarQubeDotCom(props: Props) {
 
   return (
     <div className="sqcom-about-rules">
-      <div className="about-page-container">
+      <div className="page-limited">
         <Link to={getRulesUrl(null, organization)} className="sqcom-about-rules-link">
           +3,000 rules
           <span className="spacer-left">
index dc5a19e05594c3c10e397d7f73f03da6e11af1e2..88db615075e6738afbe85ed12e2f62ce5b0e8e47 100644 (file)
   color: #4b9fd5;
 }
 
-.sqcom-about-page-entry .about-page-container {
+.sqcom-about-page-entry .page-limited {
   display: flex;
   justify-content: space-between;
   align-items: center;
+  padding-top: 0;
+  padding-bottom: 0;
 }
 
 .sqcom-about-page-intro {
   background-color: #4193c8;
 }
 
-.sqcom-about-rules .about-page-container {
+.sqcom-about-rules .page-limited {
   display: flex;
   justify-content: space-between;
   align-items: center;
+  padding-top: 0;
+  padding-bottom: 0;
 }
 
 .sqcom-about-rules .button {
index 46a0e9added29201501b51b79b0ea0a6cedd1c80..a81e5434c6ff90ce44c38d6994a691b1f5a9f220 100644 (file)
   padding-bottom: 25px;
 }
 
-.about-page-container {
-  position: relative;
-  width: 1080px;
-  margin-left: auto;
-  margin-right: auto;
-  padding-left: 20px;
-  padding-right: 20px;
-  box-sizing: border-box;
-}
-
 .about-page-entry {
   display: flex;
   justify-content: space-between;
index 10410996517086bcac9c7519c0dd9a40b9344a46..6050ad059294a29761d738927852a34c247169a5 100644 (file)
   padding-top: 11px;
 }
 
-.account-nav .nav-tabs {
-  width: 100%;
-  border-bottom: none;
-}
-
-.account-nav .navbar-nav > li > a {
-  padding-top: 8px;
-  padding-bottom: 8px;
-}
-
 .account-user {
   float: left;
 }
index 65c06efeb12b1b27ee6566606a16a0bb262efb8f..d8d39380cd53f584b21f8e8914f5eb174dcf3fa1 100644 (file)
@@ -20,6 +20,7 @@
 // @flow
 import React from 'react';
 import { Link, IndexLink } from 'react-router';
+import NavBarTabs from '../../../components/nav/NavBarTabs';
 import { translate } from '../../../helpers/l10n';
 
 type Props = {
@@ -28,8 +29,8 @@ type Props = {
 
 export default function Nav({ customOrganizations }: Props) {
   return (
-    <nav className="account-nav clearfix">
-      <ul className="nav navbar-nav nav-tabs">
+    <nav className="account-nav">
+      <NavBarTabs>
         <li>
           <IndexLink to="/account/" activeClassName="active">
             {translate('my_account.profile')}
@@ -57,7 +58,7 @@ export default function Nav({ customOrganizations }: Props) {
               {translate('my_account.organizations')}
             </Link>
           </li>}
-      </ul>
+      </NavBarTabs>
     </nav>
   );
 }
index 1c6f8c433bacc904a911c956090d689f8eb3a274..b72fcf31384dfb6baf84ff95a371f239745605dd 100644 (file)
   border: 1px solid #e6e6e6;
   background-color: #fff;
 }
+
+.nav-pills > ul {
+  display: flex;
+  flex-wrap: wrap;
+}
+
+.nav-pills > ul > li > a {
+  display: inline-block;
+  vertical-align: middle;
+  padding: 3px 10px;
+  border: 1px solid transparent;
+  border-radius: 24px;
+  color: #236a97;
+  transition: none;
+}
+
+.nav-pills > ul > li > a:hover {
+  border-color: #236a97;
+}
+
+.nav-pills > ul > li.active > a,
+.nav-pills > ul > li > a.active {
+  background-color: #236a97;
+  color: #fff;
+}
index 3d1a53be793bba2cf5f9601159dbf76b9124108b..bb0f41ec65ba4fa70d59e8bf06458c291dccc310 100644 (file)
   text-align: right;
 }
 
-.issues .search-navigator-facet-header,
-.issues .search-navigator-facet-list {
-  padding-left: 0;
-  padding-right: 0;
-}
-
-.issues .search-navigator-facet-header {
-  padding-top: 8px;
-  padding-bottom: 8px;
-}
-
-.issues .search-navigator-facet-box:not(.hidden):not(.leak-facet-box)
-  + .search-navigator-facet-box:not(.leak-facet-box) {
-  border-top: none;
-}
-
 .issues .search-navigator-facet-footer {
   padding: 0 0 10px 0;
 }
index 370b2bc4dfb9127a50d8ad8734504f09f854bd04..e872e6e2ac1ce46d84fe025dac24b4232ac5bf07 100644 (file)
 // @flow
 import React from 'react';
 import { Link } from 'react-router';
+import classNames from 'classnames';
 import { translate } from '../../../helpers/l10n';
-import OrganizationIcon from '../../../components/ui/OrganizationIcon';
+import ContextNavBar from '../../../components/nav/ContextNavBar';
+import NavBarTabs from '../../../components/nav/NavBarTabs';
+import OrganizationIcon from '../../../components/icons-components/OrganizationIcon';
 import type { Organization } from '../../../store/organizations/duck';
 
 const ADMIN_PATHS = [
@@ -43,8 +46,11 @@ export default class OrganizationNavigation extends React.PureComponent {
     const { organization } = this.props;
 
     return (
-      <li className={adminActive ? 'active' : ''}>
-        <a className="dropdown-toggle navbar-admin-link" data-toggle="dropdown" href="#">
+      <li className="dropdown">
+        <a
+          className={classNames('dropdown-toggle', 'is-admin', { active: adminActive })}
+          data-toggle="dropdown"
+          href="#">
           {translate('layout.settings')}&nbsp;<i className="icon-dropdown" />
         </a>
         <ul className="dropdown-menu">
@@ -145,75 +151,72 @@ export default class OrganizationNavigation extends React.PureComponent {
     const moreActive = !adminActive && location.pathname.includes('/extension/');
 
     return (
-      <nav className="navbar navbar-context page-container" id="context-navigation">
-        <div className="navbar-context-inner">
-          <div className="container">
-            <h2 className="navbar-context-title">
-              <span className="navbar-context-title-qualifier little-spacer-right">
-                <OrganizationIcon />
-              </span>
-              <Link to={`/organizations/${organization.key}`} className="link-base-color">
-                <strong>
-                  {organization.name}
-                </strong>
-              </Link>
-            </h2>
-
-            {organization.description != null &&
-              <div className="navbar-context-description">
-                <p className="text-limited text-top" title={organization.description}>
-                  {organization.description}
-                </p>
-              </div>}
-
-            <div className="navbar-context-meta">
-              {!!organization.avatar &&
-                <img src={organization.avatar} height={30} alt={organization.name} />}
-              {organization.url != null &&
-                <div>
-                  <p className="text-limited text-top">
-                    <a
-                      className="link-underline"
-                      href={organization.url}
-                      title={organization.url}
-                      rel="nofollow">
-                      {organization.url}
-                    </a>
-                  </p>
-                </div>}
-            </div>
+      <ContextNavBar id="context-navigation" height={65}>
+        <div className="navbar-context-header">
+          <h1 className="display-inline-block">
+            <OrganizationIcon className="little-spacer-right" />
+            <Link
+              to={`/organizations/${organization.key}`}
+              className="link-base-color link-no-underline">
+              <strong>
+                {organization.name}
+              </strong>
+            </Link>
+          </h1>
+          {organization.description != null &&
+            <div className="navbar-context-description">
+              <p className="text-limited text-top" title={organization.description}>
+                {organization.description}
+              </p>
+            </div>}
+        </div>
 
-            <ul className="nav navbar-nav nav-tabs">
-              <li>
-                <Link
-                  to={`/organizations/${organization.key}/projects`}
-                  className={isHomeActive ? 'active' : ''}>
-                  {translate('projects.page')}
-                </Link>
-              </li>
-              <li>
-                <Link to={`/organizations/${organization.key}/members`} activeClassName="active">
-                  {translate('organization.members.page')}
-                </Link>
-              </li>
-              <li>
-                <Link
-                  to={`/organizations/${organization.key}/quality_profiles`}
-                  activeClassName="active">
-                  {translate('quality_profiles.page')}
-                </Link>
-              </li>
-              <li>
-                <Link to={`/organizations/${organization.key}/rules`} activeClassName="active">
-                  {translate('coding_rules.page')}
-                </Link>
-              </li>
-              {this.renderExtensions(moreActive)}
-              {organization.canAdmin && this.renderAdministration(adminActive)}
-            </ul>
-          </div>
+        <div className="navbar-context-meta">
+          {!!organization.avatar &&
+            <img src={organization.avatar} height={30} alt={organization.name} />}
+          {organization.url != null &&
+            <div>
+              <p className="text-limited text-top">
+                <a
+                  className="link-underline"
+                  href={organization.url}
+                  title={organization.url}
+                  rel="nofollow">
+                  {organization.url}
+                </a>
+              </p>
+            </div>}
         </div>
-      </nav>
+
+        <NavBarTabs>
+          <li>
+            <Link
+              to={`/organizations/${organization.key}/projects`}
+              className={isHomeActive ? 'active' : ''}>
+              {translate('projects.page')}
+            </Link>
+          </li>
+          <li>
+            <Link to={`/organizations/${organization.key}/members`} activeClassName="active">
+              {translate('organization.members.page')}
+            </Link>
+          </li>
+          <li>
+            <Link
+              to={`/organizations/${organization.key}/quality_profiles`}
+              activeClassName="active">
+              {translate('quality_profiles.page')}
+            </Link>
+          </li>
+          <li>
+            <Link to={`/organizations/${organization.key}/rules`} activeClassName="active">
+              {translate('coding_rules.page')}
+            </Link>
+          </li>
+          {this.renderExtensions(moreActive)}
+          {organization.canAdmin && this.renderAdministration(adminActive)}
+        </NavBarTabs>
+      </ContextNavBar>
     );
   }
 }
index 06ffb28889b8b3043bc8c69527d4458c12387536..05104c2e4d81446e1ecc4de6bed0b1552df7cfbb 100644 (file)
 // Jest Snapshot v1, https://goo.gl/fbAQLP
 
 exports[`admin 1`] = `
-<nav
-  className="navbar navbar-context page-container"
+<ContextNavBar
+  height={65}
   id="context-navigation"
 >
   <div
-    className="navbar-context-inner"
+    className="navbar-context-header"
   >
-    <div
-      className="container"
+    <h1
+      className="display-inline-block"
     >
-      <h2
-        className="navbar-context-title"
-      >
-        <span
-          className="navbar-context-title-qualifier little-spacer-right"
-        >
-          <OrganizationIcon />
-        </span>
-        <Link
-          className="link-base-color"
-          onlyActiveOnIndex={false}
-          style={Object {}}
-          to="/organizations/foo"
-        >
-          <strong>
-            Foo
-          </strong>
-        </Link>
-      </h2>
-      <div
-        className="navbar-context-meta"
+      <OrganizationIcon
+        className="little-spacer-right"
       />
+      <Link
+        className="link-base-color link-no-underline"
+        onlyActiveOnIndex={false}
+        style={Object {}}
+        to="/organizations/foo"
+      >
+        <strong>
+          Foo
+        </strong>
+      </Link>
+    </h1>
+  </div>
+  <div
+    className="navbar-context-meta"
+  />
+  <NavBarTabs>
+    <li>
+      <Link
+        className=""
+        onlyActiveOnIndex={false}
+        style={Object {}}
+        to="/organizations/foo/projects"
+      >
+        projects.page
+      </Link>
+    </li>
+    <li>
+      <Link
+        activeClassName="active"
+        onlyActiveOnIndex={false}
+        style={Object {}}
+        to="/organizations/foo/members"
+      >
+        organization.members.page
+      </Link>
+    </li>
+    <li>
+      <Link
+        activeClassName="active"
+        onlyActiveOnIndex={false}
+        style={Object {}}
+        to="/organizations/foo/quality_profiles"
+      >
+        quality_profiles.page
+      </Link>
+    </li>
+    <li>
+      <Link
+        activeClassName="active"
+        onlyActiveOnIndex={false}
+        style={Object {}}
+        to="/organizations/foo/rules"
+      >
+        coding_rules.page
+      </Link>
+    </li>
+    <li
+      className="dropdown"
+    >
+      <a
+        className="dropdown-toggle is-admin"
+        data-toggle="dropdown"
+        href="#"
+      >
+        layout.settings
+        Â 
+        <i
+          className="icon-dropdown"
+        />
+      </a>
       <ul
-        className="nav navbar-nav nav-tabs"
+        className="dropdown-menu"
       >
-        <li>
-          <Link
-            className=""
-            onlyActiveOnIndex={false}
-            style={Object {}}
-            to="/organizations/foo/projects"
-          >
-            projects.page
-          </Link>
-        </li>
         <li>
           <Link
             activeClassName="active"
             onlyActiveOnIndex={false}
             style={Object {}}
-            to="/organizations/foo/members"
+            to="/organizations/foo/groups"
           >
-            organization.members.page
+            user_groups.page
           </Link>
         </li>
         <li>
@@ -61,9 +102,9 @@ exports[`admin 1`] = `
             activeClassName="active"
             onlyActiveOnIndex={false}
             style={Object {}}
-            to="/organizations/foo/quality_profiles"
+            to="/organizations/foo/permissions"
           >
-            quality_profiles.page
+            permissions.page
           </Link>
         </li>
         <li>
@@ -71,140 +112,9 @@ exports[`admin 1`] = `
             activeClassName="active"
             onlyActiveOnIndex={false}
             style={Object {}}
-            to="/organizations/foo/rules"
+            to="/organizations/foo/permission_templates"
           >
-            coding_rules.page
-          </Link>
-        </li>
-        <li
-          className=""
-        >
-          <a
-            className="dropdown-toggle navbar-admin-link"
-            data-toggle="dropdown"
-            href="#"
-          >
-            layout.settings
-            Â 
-            <i
-              className="icon-dropdown"
-            />
-          </a>
-          <ul
-            className="dropdown-menu"
-          >
-            <li>
-              <Link
-                activeClassName="active"
-                onlyActiveOnIndex={false}
-                style={Object {}}
-                to="/organizations/foo/groups"
-              >
-                user_groups.page
-              </Link>
-            </li>
-            <li>
-              <Link
-                activeClassName="active"
-                onlyActiveOnIndex={false}
-                style={Object {}}
-                to="/organizations/foo/permissions"
-              >
-                permissions.page
-              </Link>
-            </li>
-            <li>
-              <Link
-                activeClassName="active"
-                onlyActiveOnIndex={false}
-                style={Object {}}
-                to="/organizations/foo/permission_templates"
-              >
-                permission_templates
-              </Link>
-            </li>
-            <li>
-              <Link
-                activeClassName="active"
-                onlyActiveOnIndex={false}
-                style={Object {}}
-                to="/organizations/foo/projects_management"
-              >
-                projects_management
-              </Link>
-            </li>
-            <li>
-              <Link
-                activeClassName="active"
-                onlyActiveOnIndex={false}
-                style={Object {}}
-                to="/organizations/foo/edit"
-              >
-                edit
-              </Link>
-            </li>
-            <li>
-              <Link
-                activeClassName="active"
-                onlyActiveOnIndex={false}
-                style={Object {}}
-                to="/organizations/foo/delete"
-              >
-                delete
-              </Link>
-            </li>
-          </ul>
-        </li>
-      </ul>
-    </div>
-  </div>
-</nav>
-`;
-
-exports[`regular user 1`] = `
-<nav
-  className="navbar navbar-context page-container"
-  id="context-navigation"
->
-  <div
-    className="navbar-context-inner"
-  >
-    <div
-      className="container"
-    >
-      <h2
-        className="navbar-context-title"
-      >
-        <span
-          className="navbar-context-title-qualifier little-spacer-right"
-        >
-          <OrganizationIcon />
-        </span>
-        <Link
-          className="link-base-color"
-          onlyActiveOnIndex={false}
-          style={Object {}}
-          to="/organizations/foo"
-        >
-          <strong>
-            Foo
-          </strong>
-        </Link>
-      </h2>
-      <div
-        className="navbar-context-meta"
-      />
-      <ul
-        className="nav navbar-nav nav-tabs"
-      >
-        <li>
-          <Link
-            className=""
-            onlyActiveOnIndex={false}
-            style={Object {}}
-            to="/organizations/foo/projects"
-          >
-            projects.page
+            permission_templates
           </Link>
         </li>
         <li>
@@ -212,9 +122,9 @@ exports[`regular user 1`] = `
             activeClassName="active"
             onlyActiveOnIndex={false}
             style={Object {}}
-            to="/organizations/foo/members"
+            to="/organizations/foo/projects_management"
           >
-            organization.members.page
+            projects_management
           </Link>
         </li>
         <li>
@@ -222,9 +132,9 @@ exports[`regular user 1`] = `
             activeClassName="active"
             onlyActiveOnIndex={false}
             style={Object {}}
-            to="/organizations/foo/quality_profiles"
+            to="/organizations/foo/edit"
           >
-            quality_profiles.page
+            edit
           </Link>
         </li>
         <li>
@@ -232,61 +142,186 @@ exports[`regular user 1`] = `
             activeClassName="active"
             onlyActiveOnIndex={false}
             style={Object {}}
-            to="/organizations/foo/rules"
+            to="/organizations/foo/delete"
           >
-            coding_rules.page
+            delete
           </Link>
         </li>
       </ul>
-    </div>
+    </li>
+  </NavBarTabs>
+</ContextNavBar>
+`;
+
+exports[`regular user 1`] = `
+<ContextNavBar
+  height={65}
+  id="context-navigation"
+>
+  <div
+    className="navbar-context-header"
+  >
+    <h1
+      className="display-inline-block"
+    >
+      <OrganizationIcon
+        className="little-spacer-right"
+      />
+      <Link
+        className="link-base-color link-no-underline"
+        onlyActiveOnIndex={false}
+        style={Object {}}
+        to="/organizations/foo"
+      >
+        <strong>
+          Foo
+        </strong>
+      </Link>
+    </h1>
   </div>
-</nav>
+  <div
+    className="navbar-context-meta"
+  />
+  <NavBarTabs>
+    <li>
+      <Link
+        className=""
+        onlyActiveOnIndex={false}
+        style={Object {}}
+        to="/organizations/foo/projects"
+      >
+        projects.page
+      </Link>
+    </li>
+    <li>
+      <Link
+        activeClassName="active"
+        onlyActiveOnIndex={false}
+        style={Object {}}
+        to="/organizations/foo/members"
+      >
+        organization.members.page
+      </Link>
+    </li>
+    <li>
+      <Link
+        activeClassName="active"
+        onlyActiveOnIndex={false}
+        style={Object {}}
+        to="/organizations/foo/quality_profiles"
+      >
+        quality_profiles.page
+      </Link>
+    </li>
+    <li>
+      <Link
+        activeClassName="active"
+        onlyActiveOnIndex={false}
+        style={Object {}}
+        to="/organizations/foo/rules"
+      >
+        coding_rules.page
+      </Link>
+    </li>
+  </NavBarTabs>
+</ContextNavBar>
 `;
 
 exports[`undeletable org 1`] = `
-<nav
-  className="navbar navbar-context page-container"
+<ContextNavBar
+  height={65}
   id="context-navigation"
 >
   <div
-    className="navbar-context-inner"
+    className="navbar-context-header"
   >
-    <div
-      className="container"
+    <h1
+      className="display-inline-block"
     >
-      <h2
-        className="navbar-context-title"
-      >
-        <span
-          className="navbar-context-title-qualifier little-spacer-right"
-        >
-          <OrganizationIcon />
-        </span>
-        <Link
-          className="link-base-color"
-          onlyActiveOnIndex={false}
-          style={Object {}}
-          to="/organizations/foo"
-        >
-          <strong>
-            Foo
-          </strong>
-        </Link>
-      </h2>
-      <div
-        className="navbar-context-meta"
+      <OrganizationIcon
+        className="little-spacer-right"
       />
+      <Link
+        className="link-base-color link-no-underline"
+        onlyActiveOnIndex={false}
+        style={Object {}}
+        to="/organizations/foo"
+      >
+        <strong>
+          Foo
+        </strong>
+      </Link>
+    </h1>
+  </div>
+  <div
+    className="navbar-context-meta"
+  />
+  <NavBarTabs>
+    <li>
+      <Link
+        className=""
+        onlyActiveOnIndex={false}
+        style={Object {}}
+        to="/organizations/foo/projects"
+      >
+        projects.page
+      </Link>
+    </li>
+    <li>
+      <Link
+        activeClassName="active"
+        onlyActiveOnIndex={false}
+        style={Object {}}
+        to="/organizations/foo/members"
+      >
+        organization.members.page
+      </Link>
+    </li>
+    <li>
+      <Link
+        activeClassName="active"
+        onlyActiveOnIndex={false}
+        style={Object {}}
+        to="/organizations/foo/quality_profiles"
+      >
+        quality_profiles.page
+      </Link>
+    </li>
+    <li>
+      <Link
+        activeClassName="active"
+        onlyActiveOnIndex={false}
+        style={Object {}}
+        to="/organizations/foo/rules"
+      >
+        coding_rules.page
+      </Link>
+    </li>
+    <li
+      className="dropdown"
+    >
+      <a
+        className="dropdown-toggle is-admin"
+        data-toggle="dropdown"
+        href="#"
+      >
+        layout.settings
+        Â 
+        <i
+          className="icon-dropdown"
+        />
+      </a>
       <ul
-        className="nav navbar-nav nav-tabs"
+        className="dropdown-menu"
       >
         <li>
           <Link
-            className=""
+            activeClassName="active"
             onlyActiveOnIndex={false}
             style={Object {}}
-            to="/organizations/foo/projects"
+            to="/organizations/foo/groups"
           >
-            projects.page
+            user_groups.page
           </Link>
         </li>
         <li>
@@ -294,9 +329,9 @@ exports[`undeletable org 1`] = `
             activeClassName="active"
             onlyActiveOnIndex={false}
             style={Object {}}
-            to="/organizations/foo/members"
+            to="/organizations/foo/permissions"
           >
-            organization.members.page
+            permissions.page
           </Link>
         </li>
         <li>
@@ -304,9 +339,9 @@ exports[`undeletable org 1`] = `
             activeClassName="active"
             onlyActiveOnIndex={false}
             style={Object {}}
-            to="/organizations/foo/quality_profiles"
+            to="/organizations/foo/permission_templates"
           >
-            quality_profiles.page
+            permission_templates
           </Link>
         </li>
         <li>
@@ -314,82 +349,23 @@ exports[`undeletable org 1`] = `
             activeClassName="active"
             onlyActiveOnIndex={false}
             style={Object {}}
-            to="/organizations/foo/rules"
+            to="/organizations/foo/projects_management"
           >
-            coding_rules.page
+            projects_management
           </Link>
         </li>
-        <li
-          className=""
-        >
-          <a
-            className="dropdown-toggle navbar-admin-link"
-            data-toggle="dropdown"
-            href="#"
-          >
-            layout.settings
-            Â 
-            <i
-              className="icon-dropdown"
-            />
-          </a>
-          <ul
-            className="dropdown-menu"
+        <li>
+          <Link
+            activeClassName="active"
+            onlyActiveOnIndex={false}
+            style={Object {}}
+            to="/organizations/foo/edit"
           >
-            <li>
-              <Link
-                activeClassName="active"
-                onlyActiveOnIndex={false}
-                style={Object {}}
-                to="/organizations/foo/groups"
-              >
-                user_groups.page
-              </Link>
-            </li>
-            <li>
-              <Link
-                activeClassName="active"
-                onlyActiveOnIndex={false}
-                style={Object {}}
-                to="/organizations/foo/permissions"
-              >
-                permissions.page
-              </Link>
-            </li>
-            <li>
-              <Link
-                activeClassName="active"
-                onlyActiveOnIndex={false}
-                style={Object {}}
-                to="/organizations/foo/permission_templates"
-              >
-                permission_templates
-              </Link>
-            </li>
-            <li>
-              <Link
-                activeClassName="active"
-                onlyActiveOnIndex={false}
-                style={Object {}}
-                to="/organizations/foo/projects_management"
-              >
-                projects_management
-              </Link>
-            </li>
-            <li>
-              <Link
-                activeClassName="active"
-                onlyActiveOnIndex={false}
-                style={Object {}}
-                to="/organizations/foo/edit"
-              >
-                edit
-              </Link>
-            </li>
-          </ul>
+            edit
+          </Link>
         </li>
       </ul>
-    </div>
-  </div>
-</nav>
+    </li>
+  </NavBarTabs>
+</ContextNavBar>
 `;
diff --git a/server/sonar-web/src/main/js/components/icons-components/OrganizationIcon.js b/server/sonar-web/src/main/js/components/icons-components/OrganizationIcon.js
new file mode 100644 (file)
index 0000000..225b3f9
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * 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';
+
+type Props = { className?: string, size?: number };
+
+export default function OrganizationIcon({ className, size = 16 }: Props) {
+  /* eslint-disable max-len */
+  return (
+    <svg
+      xmlns="http://www.w3.org/2000/svg"
+      className={className}
+      height={size}
+      width={size}
+      viewBox="0 0 16 16">
+      <path
+        style={{ fill: '#4b9fd5' }}
+        d="M13.5 6c-.4 0-.7.1-1.1.2L11 4.8v-.3C11 3.1 9.9 2 8.5 2S6 3.1 6 4.5v.2L4.5 6.2c-.3-.1-.7-.2-1-.2C2.1 6 1 7.1 1 8.5S2.1 11 3.5 11 6 9.9 6 8.5c0-.7-.3-1.3-.7-1.7l1-1c.4.6 1 1 1.7 1.1V9c-1.1.2-2 1.2-2 2.4C6 12.9 7.1 14 8.5 14s2.5-1.1 2.5-2.5c0-1.2-.9-2.2-2-2.4V6.9c.7-.1 1.2-.5 1.6-1.1l1 1c-.4.4-.6 1-.6 1.6 0 1.4 1.1 2.5 2.5 2.5s2.5-1 2.5-2.4S14.9 6 13.5 6zm-10 4C2.7 10 2 9.3 2 8.5S2.7 7 3.5 7 5 7.7 5 8.5 4.3 10 3.5 10zm6.5 1.5c0 .8-.7 1.5-1.5 1.5S7 12.3 7 11.5 7.7 10 8.5 10s1.5.7 1.5 1.5zM8.5 6C7.7 6 7 5.3 7 4.5S7.7 3 8.5 3s1.5.7 1.5 1.5S9.3 6 8.5 6zm5 4c-.8 0-1.5-.7-1.5-1.5S12.7 7 13.5 7s1.5.7 1.5 1.5-.7 1.5-1.5 1.5z"
+      />
+    </svg>
+  );
+}
diff --git a/server/sonar-web/src/main/js/components/nav/ContextNavBar.css b/server/sonar-web/src/main/js/components/nav/ContextNavBar.css
new file mode 100644 (file)
index 0000000..ebebf69
--- /dev/null
@@ -0,0 +1,36 @@
+.navbar-context,
+.navbar-context .navbar-inner {
+  background-color: #f3f3f3;
+  z-index: 420;
+}
+
+.navbar-context .navbar-inner {
+  padding-top: 5px;
+  border-bottom: 1px solid #e6e6e6;
+}
+
+.navbar-context-header {
+  line-height: 30px;
+  font-size: 15px;
+}
+
+.navbar-context-meta {
+  position: absolute;
+  top: 0;
+  right: 0;
+  line-height: 30px;
+  padding: 0 10px;
+  color: #777;
+  font-size: 12px;
+  text-align: right;
+}
+
+.navbar-context-description {
+  display: inline-block;
+  line-height: 24px;
+  margin-left: 16px;
+  padding-top: 4px;
+  padding-left: 4px;
+  color: #777;
+  font-size: 12px;
+}
diff --git a/server/sonar-web/src/main/js/components/nav/ContextNavBar.js b/server/sonar-web/src/main/js/components/nav/ContextNavBar.js
new file mode 100644 (file)
index 0000000..003a061
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ * 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 classNames from 'classnames';
+import NavBar from './NavBar';
+import './ContextNavBar.css';
+
+type Props = {
+  className?: string,
+  height: number
+};
+
+export default function ContextNavBar({ className, ...other }: Props) {
+  return <NavBar className={classNames('navbar-context', className)} {...other} />;
+}
diff --git a/server/sonar-web/src/main/js/components/nav/NavBar.css b/server/sonar-web/src/main/js/components/nav/NavBar.css
new file mode 100644 (file)
index 0000000..c74c092
--- /dev/null
@@ -0,0 +1,24 @@
+.navbar,
+[class^="navbar-"],
+[class*=" navbar-"] {
+  box-sizing: border-box;
+}
+
+.navbar {
+}
+
+.navbar-inner {
+  position: fixed;
+  left: 0;
+  right: 0;
+}
+
+.navbar-limited {
+  position: relative;
+  min-width: 1100px;
+  max-width: 1320px;
+  margin-left: auto;
+  margin-right: auto;
+  padding-left: 20px;
+  padding-right: 20px;
+}
diff --git a/server/sonar-web/src/main/js/components/nav/NavBar.js b/server/sonar-web/src/main/js/components/nav/NavBar.js
new file mode 100644 (file)
index 0000000..beb4466
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * 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 classNames from 'classnames';
+import './NavBar.css';
+
+type Props = {
+  children?: React.Element<*>,
+  className?: string,
+  height: number
+};
+
+export default function NavBar({ children, className, height, ...other }: Props) {
+  return (
+    <nav {...other} className={classNames('navbar', className)} style={{ height }}>
+      <div className="navbar-inner" style={{ height }}>
+        <div className="navbar-limited clearfix">
+          {children}
+        </div>
+      </div>
+    </nav>
+  );
+}
diff --git a/server/sonar-web/src/main/js/components/nav/NavBarTabs.css b/server/sonar-web/src/main/js/components/nav/NavBarTabs.css
new file mode 100644 (file)
index 0000000..b716dad
--- /dev/null
@@ -0,0 +1,28 @@
+.navbar-tabs {
+  display: flex;
+  align-items: center;
+}
+
+.navbar-tabs > li + li {
+  margin-left: 20px;
+}
+
+.navbar-tabs > li > a {
+  display: block;
+  padding: 7px 0 4px;
+  border-bottom: 3px solid transparent;
+  color: #444;
+  transition: none;
+}
+
+.navbar-tabs > li > a.active,
+.navbar-tabs > li > a:hover,
+.navbar-tabs > li > a:focus {
+  border-bottom-color: #4b9fd5;
+}
+
+.navbar-tabs > li > a.is-admin.active,
+.navbar-tabs > li > a.is-admin:hover,
+.navbar-tabs > li > a.is-admin:focus {
+  border-bottom-color: #ed7d20;
+}
diff --git a/server/sonar-web/src/main/js/components/nav/NavBarTabs.js b/server/sonar-web/src/main/js/components/nav/NavBarTabs.js
new file mode 100644 (file)
index 0000000..f1d8e29
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * 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 classNames from 'classnames';
+import './NavBarTabs.css';
+
+type Props = {
+  children?: React.Element<*>,
+  className?: string
+};
+
+export default function NavBarTabs({ children, className, ...other }: Props) {
+  return (
+    <ul {...other} className={classNames('navbar-tabs', className)}>
+      {children}
+    </ul>
+  );
+}
diff --git a/server/sonar-web/src/main/js/components/ui/OrganizationIcon.js b/server/sonar-web/src/main/js/components/ui/OrganizationIcon.js
deleted file mode 100644 (file)
index 4b0de90..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * 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';
-
-export default function OrganizationIcon() {
-  /* eslint-disable max-len */
-  return (
-    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16">
-      <path
-        style={{ fill: '#4b9fd5' }}
-        d="M13.5 6c-.4 0-.7.1-1.1.2L11 4.8v-.3C11 3.1 9.9 2 8.5 2S6 3.1 6 4.5v.2L4.5 6.2c-.3-.1-.7-.2-1-.2C2.1 6 1 7.1 1 8.5S2.1 11 3.5 11 6 9.9 6 8.5c0-.7-.3-1.3-.7-1.7l1-1c.4.6 1 1 1.7 1.1V9c-1.1.2-2 1.2-2 2.4C6 12.9 7.1 14 8.5 14s2.5-1.1 2.5-2.5c0-1.2-.9-2.2-2-2.4V6.9c.7-.1 1.2-.5 1.6-1.1l1 1c-.4.4-.6 1-.6 1.6 0 1.4 1.1 2.5 2.5 2.5s2.5-1 2.5-2.4S14.9 6 13.5 6zm-10 4C2.7 10 2 9.3 2 8.5S2.7 7 3.5 7 5 7.7 5 8.5 4.3 10 3.5 10zm6.5 1.5c0 .8-.7 1.5-1.5 1.5S7 12.3 7 11.5 7.7 10 8.5 10s1.5.7 1.5 1.5zM8.5 6C7.7 6 7 5.3 7 4.5S7.7 3 8.5 3s1.5.7 1.5 1.5S9.3 6 8.5 6zm5 4c-.8 0-1.5-.7-1.5-1.5S12.7 7 13.5 7s1.5.7 1.5 1.5-.7 1.5-1.5 1.5z"
-      />
-    </svg>
-  );
-}
index 9dd4a8b75f4e2f9f2671ec6f4819b8c45bdbd2e1..05606b9ea885fd2cc93942139148a97c71ff3a3f 100644 (file)
@@ -42,7 +42,7 @@
     clearMenus()
 
     if (!isActive) {
-      if ('ontouchstart' in document.documentElement && !$parent.closest('.navbar-nav').length) {
+      if ('ontouchstart' in document.documentElement) {
         // if mobile we use a backdrop because click events don't delegate
         $('<div class="dropdown-backdrop"/>').insertAfter($(this)).on('click', clearMenus)
       }
diff --git a/server/sonar-web/src/main/less/components/navbar.less b/server/sonar-web/src/main/less/components/navbar.less
deleted file mode 100644 (file)
index 3573ab3..0000000
+++ /dev/null
@@ -1,363 +0,0 @@
-/*
- * 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 (reference) "../mixins";
-@import (reference) "../variables";
-@import (reference) "ui";
-
-@navbarGlobalBackground: #262626;
-@navbarContextBackground: @barBackgroundColor;
-
-@navbarLineHeight: 20px;
-@navbarTopPadding: (@navbarGlobalHeight - @navbarLineHeight) / 2;
-
-.navbar,
-[class^="navbar-"],
-[class*=" navbar-"] {
-  box-sizing: border-box;
-}
-
-.navbar {
-  position: fixed;
-  left: 0;
-  right: 0;
-  .clearfix;
-  height: @navbarGlobalHeight;
-}
-
-.navbar-fade {
-  .navbar-nav {
-    opacity: 0;
-    transition: opacity 0.2s ease;
-  }
-
-  .navbar-favorite {
-    margin-right: -23px;
-    transition: margin 0.2s ease;
-  }
-
-  &.in {
-    .navbar-nav {
-      opacity: 1;
-    }
-
-    .navbar-favorite {
-      margin-right: 0;
-    }
-  }
-}
-
-.navbar a {
-  .link-no-underline;
-  transition: none;
-}
-
-.navbar-header {
-  float: left;
-}
-
-.navbar-brand {
-  display: block;
-
-  img {
-    vertical-align: top;
-  }
-}
-
-.navbar-brand-custom {
-  padding: 0 10px;
-}
-
-.navbar-nav {
-  float: left;
-}
-
-.navbar-nav > li {
-  float: left;
-}
-
-.navbar-nav > li > a {
-  padding: @navbarTopPadding 10px;
-  line-height: @navbarLineHeight;
-
-  &.navbar-avatar {
-    margin-right: 7px;
-    padding: 3px;
-  }
-
-  &.navbar-help {
-    line-height: 16px;
-    padding: 7px;
-  }
-}
-
-.navbar-nav > li.navbar-more > a {
-  padding-right: 17px;
-}
-
-.navbar-nav > li.navbar-more + li {
-  margin-left: -17px;
-}
-
-.navbar-nav > li.navbar-more + li > a {
-  padding-left: 5px;
-  padding-right: 5px;
-}
-
-.navbar-icon:before {
-  color: #fff !important;
-  font-size: @iconFontSize;
-}
-
-.navbar-favorite {
-  position: relative;
-  top: -2px;
-}
-
-.navbar-right {
-  float: right;
-}
-
-.navbar-search {
-  position: relative;
-  padding-right: 3px;
-}
-
-.navbar-search-input {
-  vertical-align: middle;
-  width: 310px;
-  margin-top: 3px;
-  margin-bottom: 3px;
-  padding-left: 26px !important;
-}
-
-.navbar-search-input-hint {
-  position: absolute;
-  top: 4px;
-  right: 30px;
-  line-height: @formControlHeight;
-  font-size: 12px;
-  color: @secondFontColor;
-
-  &.is-shifted {
-    z-index: @dropdown-menu-z-index + 1;
-    top: 32px;
-  }
-}
-
-.navbar-search-icon {
-  position: relative;
-  vertical-align: middle;
-  width: 16px;
-  margin-right: -20px;
-  color: @secondFontColor;
-
-  &:before {
-    font-size: @iconSmallFontSize;
-  }
-}
-
-.navbar-search-item-link {
-  display: flex !important;
-}
-
-.navbar-search-item-match {
-  flex-grow: 5;
-  overflow: hidden;
-  text-overflow: ellipsis;
-}
-
-.navbar-search-item-right {
-  flex-grow: 1;
-  padding-left: 10px;
-  text-align: right;
-}
-
-.navbar-search-item-icons {
-  position: relative;
-  flex-shrink: 0;
-  width: 16px;
-  height: 16px;
-
-  > * {
-    position: absolute;
-    z-index: 5;
-    top: 0;
-    left: 0;
-  }
-
-  > .icon-star,
-  > .icon-clock {
-    z-index: 6;
-    top: -4px;
-    left: -5px;
-  }
-}
-
-.navbar-search-shortcut-hint {
-  line-height: 16px;
-  margin-top: 5px;
-  padding: 5px 10px;
-  border-top: 1px solid #e6e6e6;
-  background-color: #f3f3f3;
-  color: #777;
-  font-size: 11px;
-}
-
-.navbar-search-no-results {
-  margin-top: 4px;
-  padding: 5px 10px;
-}
-
-.navbar-global {
-  top: 0;
-  z-index: @navbar-global-z-index;
-  background-color: @navbarGlobalBackground;
-
-  .navbar-nav > li > a {
-    color: #ccc;
-    font-size: 12px;
-    letter-spacing: 0.05em;
-
-    &:hover {
-      color: #fff;
-    }
-  }
-
-  .navbar-nav > .active > a,
-  .navbar-nav > li > a.active,
-  .navbar-nav > .dropdown.open > a {
-    color: #fff;
-  }
-
-  .navbar-brand:hover,
-  .navbar-brand:focus {
-    background-color: darken(@navbarGlobalBackground, 20%);
-  }
-
-  .navbar-nav > li > a:hover,
-  .navbar-nav > .active > a,
-  .navbar-nav > li > a.active,
-  .navbar-nav > .dropdown.open > a {
-    background-color: @blue;
-  }
-
-  .navbar-search-dropdown {
-    background-color: @blue !important;
-  }
-
-  .navbar-admin-link:hover,
-  .active > .navbar-admin-link,
-  .active.navbar-admin-link {
-    background-color: @orange !important;
-  }
-}
-
-.navbar-global-login-github {
-  margin-top: 3px;
-  margin-right: 4px;
-}
-
-.navbar-context {
-  position: static;
-  top: @navbarGlobalHeight;
-  z-index: @navbar-context-z-index;
-  height: @navbarContextHeight;
-  padding: 0;
-  background-color: @navbarContextBackground;
-
-  .nav-tabs {
-    width: 100%;
-  }
-
-  .navbar-nav > li > a {
-    padding-top: 3px;
-    padding-bottom: 3px;
-  }
-
-  .navbar-admin-link:hover,
-  .navbar-admin-link:focus,
-  .active > .navbar-admin-link {
-    border-color: @orange !important;
-  }
-}
-
-.navbar-context-favorite {
-  float: left;
-  padding: 7px 0 0 10px;
-}
-
-.navbar-context-meta {
-  position: absolute;
-  top: 0;
-  right: 0;
-  line-height: @navbarGlobalHeight;
-  padding: 5px 10px 0;
-  color: @secondFontColor;
-  font-size: @smallFontSize;
-  text-align: right;
-}
-
-.navbar-context-description {
-  float: left;
-  line-height: @formControlHeight;
-  padding-top: 4px;
-  padding-left: 4px;
-  color: @secondFontColor;
-  font-size: @smallFontSize;
-}
-
-.navbar-context-inner {
-  position: fixed;
-  z-index: 420;
-  left: 0;
-  right: 0;
-  height: 65px;
-  padding-top: 5px;
-  box-sizing: border-box;
-  background-color: #f3f3f3;
-}
-
-.navbar-context-title {
-  float: left;
-  min-height: 30px;
-  padding: 2px 10px 0;
-}
-
-.navbar-context-title-qualifier {
-  display: inline-block;
-  line-height: 16px;
-  padding-top: 5px;
-  box-sizing: border-box;
-}
-
-.navbar-side {
-  padding: 10px;
-  border-bottom: 1px solid @barBorderColor;
-  background-color: #e5f1f9;
-}
-
-.global-navbar-search-dropdown {
-  max-height: 80vh;
-  width: 440px;
-  padding: 0;
-  overflow-y: auto;
-  overflow-x: hidden;
-  box-shadow: @defaultShadow;
-}
index 57f76aa02aceaacf205ea0a2e2ddf8f173add33b..22fce0f068ffeb2dda375aeea784add84870ced1 100644 (file)
   margin: 100px 0;
 }
 
-.page-wrapper-global {
-  padding-top: @navbarGlobalHeight;
-}
-
-.page-wrapper-context {
-  padding-top: @navbarGlobalHeight + @navbarContextHeight;
-}
-
 .page-simple {
   width: 400px;
   padding: 40px;
 }
 
 .layout-page-side-outer {
-  width: ~"calc(50vw - 360px)";
+  width: ~"calc(50vw - 370px)";
   flex-grow: 0;
   flex-shrink: 0;
   background-color: #f3f3f3;
   top: 30px;
   bottom: 0;
   left: 0;
-  width: ~"calc(50vw - 360px)";
+  width: ~"calc(50vw - 370px)";
   border-right: 1px solid #e6e6e6;
   overflow-y: auto;
   overflow-x: hidden;
 
 .layout-page-side-inner {
   width: 300px;
-  margin-left: ~"calc(50vw - 660px)";
+  margin-left: ~"calc(50vw - 670px)";
   background-color: #f3f3f3;
 }
 
 }
 
 .layout-page-main-header-inner {
-  left: ~"calc(50vw - 360px + 1px)";
+  left: ~"calc(50vw - 370px + 1px)";
   right: 0;
   padding-left: 20px;
   padding-right: 20px;
index eebff4f1c0b7b61494912a69541566fdcadcfafd..97961b8998804e5aaeb1ded10d0a0be92d271388 100644 (file)
   }
 }
 
-.search-navigator-facet-box:not(.hidden):not(.leak-facet-box)
-  + .search-navigator-facet-box:not(.leak-facet-box) {
-  border-top: 1px solid @barBorderColor;
-}
-
 .leak-facet-box:not(.hidden) + .leak-facet-box {
   border-top: none;
 }
 
 .search-navigator-facet-header {
   display: block;
-  padding: 6px 10px;
+  padding: 8px 0;
   border-bottom: none;
   color: @baseFontColor;
   font-weight: 600;
 }
 
 .search-navigator-facet-list {
-  margin: 0 0 0 0;
-  padding: 0 10px 10px;
+  padding-bottom: 10px;
   font-size: 0;
 }
 
index 16f8d9e45c0928feb769f4d452af232d57ca8d90..b36989335d55de5983fb3ffa6856ced7ab24ffb4 100644 (file)
   margin-right: 4px;
 }
 
-.nav {
-  margin: 0;
-  padding: 0;
-  list-style: none;
-}
-
-.nav > li {
-  position: relative;
-  display: block;
-}
-
-.nav > li > a {
-  position: relative;
-  display: inline-block;
-  vertical-align: middle;
-  padding: 10px 15px;
-}
-
-.nav-crumbs {
-  padding: 2px 0;
-
-  a {
-    color: @baseFontColorLight;
-
-    &:hover,
-    &:focus {
-      color: @blue !important;
-    }
-  }
-
-  > li {
-    font-size: 15px;
-    font-weight: 400;
-  }
-
-  > li + li:before {
-    content: "/";
-    float: left;
-    padding: 4px 0;
-    color: fade(@baseFontColor, 30%);
-  }
-
-  [class^="icon-"],
-  [class*=" icon-"] {
-    position: relative;
-    top: 3px;
-  }
-}
-
-.nav-tabs {
-  padding-top: 1px;
-  border-bottom: 1px solid @barBorderColor;
-
-  > li {
-    float: left;
-    margin-bottom: -1px;
-  }
-
-  > li > a {
-    padding-top: 2px;
-    padding-bottom: 2px;
-    margin-right: 2px;
-    border-bottom: 3px solid transparent;
-    color: @baseFontColorLight;
-
-    &:hover {
-      border-color: @blue;
-    }
-  }
-
-  > li.active > a,
-  > li > a.active {
-    border-color: @blue;
-  }
-}
-
-.nav-pills {
-  & > ul {
-    display: flex;
-    flex-wrap: wrap;
-
-    & > li > a {
-      display: inline-block;
-      vertical-align: middle;
-      padding: 3px 10px;
-      border: 1px solid transparent;
-      border-radius: 24px;
-      color: @darkBlue;
-      transition: none;
-
-      &:hover {
-        border-color: @darkBlue;
-      }
-    }
-
-    & > li.active > a,
-    & > li > a.active {
-      background-color: @darkBlue;
-      color: #fff;
-    }
-  }
-}
-
 .flash {
   background-color: transparent;
   transition: all 0.5s ease;
index 99338f742a5694aeb0d243c9dd647578eafb49d6..9390b7e905dce8576e9684ecb814148b89b1dfb5 100644 (file)
@@ -22,7 +22,6 @@
 @import (reference) "init/links";
 
 @media print {
-
   .noprint {
     display: none !important;
   }
     .link-no-underline;
   }
 
-  .navbar-global {
-    .noprint;
-  }
-
-  .page-wrapper-global {
-    padding-top: 0;
-  }
-
   .page-footer {
     .noprint;
   }
@@ -54,5 +45,4 @@
   .widget tfoot {
     display: table-row-group;
   }
-
 }
index 29e5875e709bee51d1156d6c896fe717fa6bd5d0..f13e4cd339a109928f389a4f16dd20c32fd80920 100644 (file)
@@ -47,7 +47,6 @@
 @import "components/page";
 @import "components/navigator";
 @import "components/component-name";
-@import "components/navbar";
 @import "components/select-list";
 @import "components/graphics";
 @import "components/list-groups";
index ca3a1a87f0dbe6fecaedac6fc23d85efe9cdd869..8364fdf9c785d41c4a3ee8dadafce1f001e77ac2 100644 (file)
@@ -28,7 +28,6 @@
 @baseFontSize: 13px;
 @baseLineHeight: unit(16px / @baseFontSize);
 
-
 /*
  * Code
  */
@@ -37,7 +36,6 @@
 @monoFontSize: 12px;
 @monoLineHeight: 18px;
 
-
 /*
  * Font Sizes
  */
 @mediumFontSize: 14px;
 @bigFontSize: 16px;
 
-
-
 @secondFontColor: #777;
 @headerFontSize: 16px;
 
-
-
 /*
  * Colors
  */
 
 @black: #000000;
 @white: #ffffff;
-@grey:  #efefef;
+@grey: #efefef;
 @darkGrey: #cdcdcd;
 @middleGrey: #b4b4b4;
 
@@ -98,8 +92,6 @@
 
 @formControlHeight: 24px;
 
-
-
 /*
  * Headers
  */
 @h5-font-weight: 600;
 @h6-font-weight: 600;
 
-
-
 /*
  * Icons
  */
 @resolutionFalsePositiveColor: @baseFontColor;
 @resolutionRemovedColor: @baseFontColor;
 
-
-
 /*
  * Shadows
  */
 
 @defaultShadow: 0 6px 12px rgba(0, 0, 0, .175);
 
-
-
 /*
  * Transitions
  */
 
 @defaultTransitionOptions: .2s ease;
 
-
-
 /*
  * Page
  */
 @navbarContextHeight: 65px;
 @pageFooterHeight: 60px;
 
-
 /*
  * Navigator
  */
 @navigatorPadding: 10px;
 @navigatorHeaderHeight: 40px;
 
-
-
 /*
  * z-index
  * =======
 
 @dashboard-transparent-z-index: 100;
 
-@navbar-global-z-index: 421;
 @navbar-context-z-index: 420;
 
 @workspace-nav-z-index: 451;
index 76d091305f67f66cf9148ebc8c3e1d80ace9c107..a7d994be3975a76940c0383f7eadcbaefa6d68c8 100644 (file)
@@ -32,7 +32,7 @@ import static com.codeborne.selenide.Selenide.$$;
 public class MembersPage {
 
   public MembersPage() {
-    $(".nav-tabs a.active").shouldBe(visible).shouldHave(text("Members"));
+    $(".navbar-tabs a.active").shouldBe(visible).shouldHave(text("Members"));
   }
 
   public ElementsCollection getMembers() {
index 5198fc8906210849dca16ba868face42fb38026c..590926eb229ce32c8706429e59bde55eb24efd75 100644 (file)
@@ -63,7 +63,7 @@ public class OrganizationUiExtensionsTest {
       .logIn().submitCredentials(administrator.getLogin())
       .open("/organizations/" + organization.getKey() + "/projects");
 
-    $("#context-navigation a.navbar-admin-link").click();
+    $("#context-navigation a.is-admin").click();
     $(By.linkText("Organization Admin Page")).shouldBe(Condition.visible).click();
 
     assertThat(url()).contains("uiextensionsplugin/organization_admin_page");
index db79e355e35e2fadf94b993c8a0cbc388ccc75d0..f3215b096bc545a9d1a9e366437dfae2b3e59ef0 100644 (file)
@@ -66,9 +66,8 @@ public class UiExtensionsTest {
     User administrator = tester.users().generateAdministrator();
     tester.openBrowser()
       .logIn().submitCredentials(administrator.getLogin())
-      .open("/about");
+      .open("/settings");
 
-    $(".navbar-admin-link").click();
     $("#settings-navigation-configuration").click();
     $(By.linkText("Global Admin Page")).click();