]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-10481 Fix text wrapping in breadcrumbs with branch
authorStas Vilchik <stas.vilchik@sonarsource.com>
Tue, 27 Mar 2018 13:06:37 +0000 (15:06 +0200)
committerSonarTech <sonartech@sonarsource.com>
Wed, 28 Mar 2018 18:20:58 +0000 (20:20 +0200)
server/sonar-web/src/main/js/app/components/nav/component/ComponentNav.css
server/sonar-web/src/main/js/app/components/nav/component/ComponentNav.tsx
server/sonar-web/src/main/js/app/components/nav/component/ComponentNavBranch.tsx
server/sonar-web/src/main/js/app/components/nav/component/ComponentNavHeader.tsx
server/sonar-web/src/main/js/app/components/nav/component/ComponentNavMeta.tsx
server/sonar-web/src/main/js/app/components/nav/component/__tests__/__snapshots__/ComponentNav-test.tsx.snap
server/sonar-web/src/main/js/app/components/nav/component/__tests__/__snapshots__/ComponentNavBranch-test.tsx.snap
server/sonar-web/src/main/js/app/components/nav/component/__tests__/__snapshots__/ComponentNavHeader-test.tsx.snap
server/sonar-web/src/main/js/app/components/nav/component/__tests__/__snapshots__/ComponentNavMeta-test.tsx.snap
server/sonar-web/src/main/js/app/styles/init/misc.css
server/sonar-web/src/main/js/components/nav/ContextNavBar.css

index ac7ce95e3f3a0af33adfa4f3b8a89519f34d550d..6b87dcbcb6ef996de7128d2323ff01e53d443264 100644 (file)
  * along with this program; if not, write to the Free Software Foundation,
  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  */
+.navbar-context-justified {
+  display: flex;
+  justify-content: space-between;
+}
+
 .navbar-context-branches {
   display: inline-flex;
   justify-content: center;
+  flex-shrink: 1 !important;
+  min-width: 0;
   line-height: calc(2 * var(--gridSize));
   margin-left: calc(2 * var(--gridSize));
   font-size: var(--baseFontSize);
index 38fbd68f6443d1fb10a21e3e6ca4a9d778def024..366b240f3576b51b977eceaf3f66a65b8be00b65 100644 (file)
@@ -81,20 +81,22 @@ export default class ComponentNav extends React.PureComponent<Props> {
     }
     return (
       <ContextNavBar
-        id="context-navigation"
         height={notifComponent ? theme.contextNavHeightRaw + 20 : theme.contextNavHeightRaw}
+        id="context-navigation"
         notif={notifComponent}>
-        <ComponentNavHeader
-          branchLikes={this.props.branchLikes}
-          component={this.props.component}
-          currentBranchLike={this.props.currentBranchLike}
-          // to close dropdown on any location change
-          location={this.props.location}
-        />
-        <ComponentNavMeta
-          branchLike={this.props.currentBranchLike}
-          component={this.props.component}
-        />
+        <div className="navbar-context-justified">
+          <ComponentNavHeader
+            branchLikes={this.props.branchLikes}
+            component={this.props.component}
+            currentBranchLike={this.props.currentBranchLike}
+            // to close dropdown on any location change
+            location={this.props.location}
+          />
+          <ComponentNavMeta
+            branchLike={this.props.currentBranchLike}
+            component={this.props.component}
+          />
+        </div>
         <ComponentNavMenu
           branchLike={this.props.currentBranchLike}
           component={this.props.component}
index e640d448159411b82ae9890cad17a671fb54f20f..a369fd1412a3fef829619ba7e5931b895e53819b 100644 (file)
@@ -144,7 +144,7 @@ export default class ComponentNavBranch extends React.PureComponent<Props, State
     const { currentBranchLike } = this.props;
     if (isShortLivingBranch(currentBranchLike)) {
       return currentBranchLike.isOrphan ? (
-        <span className="note big-spacer-left">
+        <span className="note big-spacer-left text-ellipsis flex-shrink">
           {translate('branches.orphan_branch')}
           <Tooltip overlay={translate('branches.orphan_branches.tooltip')}>
             <i className="icon-help spacer-left" />
@@ -157,7 +157,7 @@ export default class ComponentNavBranch extends React.PureComponent<Props, State
       );
     } else if (isPullRequest(currentBranchLike)) {
       return (
-        <span className="note big-spacer-left">
+        <span className="note big-spacer-left text-ellipsis flex-shrink">
           <FormattedMessage
             defaultMessage={translate('branches.pull_request.for_merge_into_x_from_y')}
             id="branches.pull_request.for_merge_into_x_from_y"
@@ -239,7 +239,7 @@ export default class ComponentNavBranch extends React.PureComponent<Props, State
         className={classNames('navbar-context-branches', 'dropdown', {
           open: this.state.dropdownOpen
         })}>
-        <a className="link-base-color link-no-underline" href="#" onClick={this.handleClick}>
+        <a className="link-base-color link-no-underline nowrap" href="#" onClick={this.handleClick}>
           <BranchIcon branchLike={currentBranchLike} className="little-spacer-right" />
           <Tooltip mouseEnterDelay={1} overlay={displayName}>
             <span className="text-limited text-top">{displayName}</span>
index b0d387e4fa7fbccb09312822d0537277ebc2e0b2..e6dae1fa20ca558a814d860f7c08d9a00e5ff45a 100644 (file)
@@ -51,16 +51,16 @@ export function ComponentNavHeader(props: Props) {
   return (
     <header className="navbar-context-header">
       <OrganizationHelmet
-        title={component.name}
         organization={organization && shouldOrganizationBeDisplayed ? organization : undefined}
+        title={component.name}
       />
       {organization &&
         shouldOrganizationBeDisplayed && (
           <>
             <OrganizationAvatar organization={organization} />
             <OrganizationLink
-              organization={organization}
-              className="link-base-color link-no-underline spacer-left">
+              className="navbar-context-header-breadcrumb-link link-base-color link-no-underline spacer-left"
+              organization={organization}>
               {organization.name}
             </OrganizationLink>
             <span className="slash-separator" />
@@ -93,7 +93,7 @@ function renderBreadcrumbs(breadcrumbs: Breadcrumb[]) {
       <React.Fragment key={item.key}>
         {index === 0 && <QualifierIcon className="spacer-right" qualifier={lastItem.qualifier} />}
         <Link
-          className="link-base-color link-no-underline"
+          className="navbar-context-header-breadcrumb-link link-base-color link-no-underline"
           title={item.name}
           to={getProjectUrl(item.key)}>
           {itemName}
index 57f41ffeb3d596be0a9b24146c51d798883bb0eb..d8a16d8066eabc81526e8f6212cdb275b5e7a537 100644 (file)
@@ -59,7 +59,7 @@ export function ComponentNavMeta({ branchLike, component, currentUser }: Props)
   return (
     <div className="navbar-context-meta">
       {component.analysisDate && (
-        <div className="spacer-left">
+        <div className="spacer-left text-ellipsis">
           <DateTimeFormatter date={component.analysisDate} />
         </div>
       )}
index 2d5fe354989884e3c7a7d2b364173b23064f5e05..b95d5c4732bd5855ca633b9cb88e5f17260d28b4 100644 (file)
@@ -5,42 +5,46 @@ exports[`renders 1`] = `
   height={72}
   id="context-navigation"
 >
-  <Connect(ComponentNavHeader)
-    branchLikes={Array []}
-    component={
-      Object {
-        "breadcrumbs": Array [
-          Object {
-            "key": "component",
-            "name": "component",
-            "qualifier": "TRK",
-          },
-        ],
-        "key": "component",
-        "name": "component",
-        "organization": "org",
-        "qualifier": "TRK",
+  <div
+    className="navbar-context-justified"
+  >
+    <Connect(ComponentNavHeader)
+      branchLikes={Array []}
+      component={
+        Object {
+          "breadcrumbs": Array [
+            Object {
+              "key": "component",
+              "name": "component",
+              "qualifier": "TRK",
+            },
+          ],
+          "key": "component",
+          "name": "component",
+          "organization": "org",
+          "qualifier": "TRK",
+        }
       }
-    }
-    location={Object {}}
-  />
-  <Connect(ComponentNavMeta)
-    component={
-      Object {
-        "breadcrumbs": Array [
-          Object {
-            "key": "component",
-            "name": "component",
-            "qualifier": "TRK",
-          },
-        ],
-        "key": "component",
-        "name": "component",
-        "organization": "org",
-        "qualifier": "TRK",
+      location={Object {}}
+    />
+    <Connect(ComponentNavMeta)
+      component={
+        Object {
+          "breadcrumbs": Array [
+            Object {
+              "key": "component",
+              "name": "component",
+              "qualifier": "TRK",
+            },
+          ],
+          "key": "component",
+          "name": "component",
+          "organization": "org",
+          "qualifier": "TRK",
+        }
       }
-    }
-  />
+    />
+  </div>
   <ComponentNavMenu
     component={
       Object {
index 67e5dbf7ef467b1654338de50aaae3243ce98048..498d9568f8cb49a1dd0ef16d9c12d278b7c7e3b1 100644 (file)
@@ -5,7 +5,7 @@ exports[`renders main branch 1`] = `
   className="navbar-context-branches dropdown"
 >
   <a
-    className="link-base-color link-no-underline"
+    className="link-base-color link-no-underline nowrap"
     href="#"
     onClick={[Function]}
   >
@@ -82,7 +82,7 @@ exports[`renders pull request 1`] = `
   className="navbar-context-branches dropdown"
 >
   <a
-    className="link-base-color link-no-underline"
+    className="link-base-color link-no-underline nowrap"
     href="#"
     onClick={[Function]}
   >
@@ -114,7 +114,7 @@ exports[`renders pull request 1`] = `
     />
   </a>
   <span
-    className="note big-spacer-left"
+    className="note big-spacer-left text-ellipsis flex-shrink"
   >
     <FormattedMessage
       defaultMessage="branches.pull_request.for_merge_into_x_from_y"
@@ -139,7 +139,7 @@ exports[`renders short-living branch 1`] = `
   className="navbar-context-branches dropdown"
 >
   <a
-    className="link-base-color link-no-underline"
+    className="link-base-color link-no-underline nowrap"
     href="#"
     onClick={[Function]}
   >
index dd13db8a75c181c14fc0c367f1821b69dd30b3e7..4d85fb56b116227f8252e2bdbdcc9f9918f8707a 100644 (file)
@@ -15,7 +15,7 @@ exports[`should not render breadcrumbs with one element 1`] = `
       qualifier="TRK"
     />
     <Link
-      className="link-base-color link-no-underline"
+      className="navbar-context-header-breadcrumb-link link-base-color link-no-underline"
       onlyActiveOnIndex={false}
       style={Object {}}
       title="My Project"
@@ -59,7 +59,7 @@ exports[`should render organization 1`] = `
       }
     />
     <OrganizationLink
-      className="link-base-color link-no-underline spacer-left"
+      className="navbar-context-header-breadcrumb-link link-base-color link-no-underline spacer-left"
       organization={
         Object {
           "key": "foo",
@@ -82,7 +82,7 @@ exports[`should render organization 1`] = `
       qualifier="TRK"
     />
     <Link
-      className="link-base-color link-no-underline"
+      className="navbar-context-header-breadcrumb-link link-base-color link-no-underline"
       onlyActiveOnIndex={false}
       style={Object {}}
       title="My Project"
index 06f96d32ee37417120e8399028ae48b31c40b317..ca18e4d86d33dd76c0a2f7b3497621c859792204 100644 (file)
@@ -5,7 +5,7 @@ exports[`renders meta for long-living branch 1`] = `
   className="navbar-context-meta"
 >
   <div
-    className="spacer-left"
+    className="spacer-left text-ellipsis"
   >
     <DateTimeFormatter
       date="2017-01-02T00:00:00.000Z"
@@ -32,7 +32,7 @@ exports[`renders meta for pull request 1`] = `
   className="navbar-context-meta"
 >
   <div
-    className="spacer-left"
+    className="spacer-left text-ellipsis"
   >
     <DateTimeFormatter
       date="2017-01-02T00:00:00.000Z"
@@ -78,7 +78,7 @@ exports[`renders status of short-living branch 1`] = `
   className="navbar-context-meta"
 >
   <div
-    className="spacer-left"
+    className="spacer-left text-ellipsis"
   >
     <DateTimeFormatter
       date="2017-01-02T00:00:00.000Z"
index f87994be76e3a83f90c72095f09385475a774b10..cecd341e962a1c3239ad6a2d7d752e89762ddd72 100644 (file)
@@ -302,6 +302,11 @@ td.big-spacer-top {
   flex: 1;
 }
 
+.flex-shrink {
+  flex-shrink: 1;
+  min-width: 0;
+}
+
 .space-between {
   justify-content: space-between !important;
 }
index 61b7c9756f6a739eb809b1bbd2118c25fa5492b2..8c9ff6a53bb4ee9a3cd53060692b85a51139a207 100644 (file)
   border-bottom: none;
 }
 
+/* use `min-width: 0` to cut breadcrumb links (to end with "...") */
+/* https://stackoverflow.com/questions/38223879/white-space-nowrap-breaks-flexbox-layout */
 .navbar-context-header {
   display: flex;
   align-items: center;
+  min-width: 0;
   height: calc(4 * var(--gridSize));
   font-size: var(--bigFontSize);
 }
 
+/* disallow icons and slash separators to shrink */
+.navbar-context-header > *:not(.navbar-context-header-breadcrumb-link) {
+  flex-shrink: 0;
+}
+
+.navbar-context-header-breadcrumb-link {
+  min-width: 0;
+  overflow: hidden;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+}
+
 .navbar-context-header .slash-separator {
   margin-left: var(--gridSize);
   margin-right: var(--gridSize);
   color: rgba(68, 68, 68, 0.2);
 }
 
+/* set `min-width: 0` to allow flexbox item to shrink */
+/* https://stackoverflow.com/questions/38223879/white-space-nowrap-breaks-flexbox-layout */
 .navbar-context-meta {
-  position: absolute;
-  top: 0;
-  right: 0;
   display: flex;
   align-items: center;
+  min-width: 0;
   height: calc(4 * var(--gridSize));
-  padding: 0 20px;
+  padding-left: 20px;
   color: var(--secondFontColor);
   font-size: var(--smallFontSize);
   text-align: right;