Allow some sections of the change list to overflow
On screens < 90em (approximately 1600px with default font size) wide, the `Owner`, `Branch`, `Assignee`, and `Project` sections should overflow with ellipses. `Project` is handled as a special case -- because most long project names usually resemble a directory structure, they are truncated to just the last two parts of the path, with ellipsees appearing before the leading slash. Bug: Issue 4552 Change-Id: Icf882cbcecb741fb9e46141a1fa88f5987a3e674
This commit is contained in:
		@@ -93,16 +93,20 @@ limitations under the License.
 | 
				
			|||||||
     * Example
 | 
					     * Example
 | 
				
			||||||
     * // returns 'text.html'
 | 
					     * // returns 'text.html'
 | 
				
			||||||
     * util.truncatePath.('text.html');
 | 
					     * util.truncatePath.('text.html');
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param {string} path
 | 
				
			||||||
 | 
					     * @param {number=} opt_threshold
 | 
				
			||||||
     * @return {string} Returns the truncated value of a URL.
 | 
					     * @return {string} Returns the truncated value of a URL.
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    truncatePath(path) {
 | 
					    truncatePath(path, opt_threshold) {
 | 
				
			||||||
 | 
					      const threshold = opt_threshold || 1;
 | 
				
			||||||
      const pathPieces = path.split('/');
 | 
					      const pathPieces = path.split('/');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      if (pathPieces.length < 2) {
 | 
					      if (pathPieces.length <= threshold) { return path; }
 | 
				
			||||||
        return path;
 | 
					
 | 
				
			||||||
      }
 | 
					      const index = pathPieces.length - threshold;
 | 
				
			||||||
      // Character is an ellipsis.
 | 
					      // Character is an ellipsis.
 | 
				
			||||||
      return '\u2026/' + pathPieces[pathPieces.length - 1];
 | 
					      return `\u2026/${pathPieces.slice(index).join('/')}`;
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
})(window);
 | 
					})(window);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -66,6 +66,19 @@ limitations under the License.
 | 
				
			|||||||
      assert.equal(shortenedPath, expectedPath);
 | 
					      assert.equal(shortenedPath, expectedPath);
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    test('truncatePath with opt_threshold', () => {
 | 
				
			||||||
 | 
					      const truncatePath = Gerrit.PathListBehavior.truncatePath;
 | 
				
			||||||
 | 
					      let path = 'level1/level2/level3/level4/file.js';
 | 
				
			||||||
 | 
					      let shortenedPath = truncatePath(path, 2);
 | 
				
			||||||
 | 
					      // The expected path is truncated with an ellipsis.
 | 
				
			||||||
 | 
					      const expectedPath = '\u2026/level4/file.js';
 | 
				
			||||||
 | 
					      assert.equal(shortenedPath, expectedPath);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      path = 'level2/file.js';
 | 
				
			||||||
 | 
					      shortenedPath = truncatePath(path, 2);
 | 
				
			||||||
 | 
					      assert.equal(shortenedPath, path);
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    test('truncatePath with short path should not add ellipsis', () => {
 | 
					    test('truncatePath with short path should not add ellipsis', () => {
 | 
				
			||||||
      const truncatePath = Gerrit.PathListBehavior.truncatePath;
 | 
					      const truncatePath = Gerrit.PathListBehavior.truncatePath;
 | 
				
			||||||
      const path = 'file.js';
 | 
					      const path = 'file.js';
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -15,6 +15,7 @@ limitations under the License.
 | 
				
			|||||||
-->
 | 
					-->
 | 
				
			||||||
<link rel="import" href="../../../behaviors/base-url-behavior/base-url-behavior.html">
 | 
					<link rel="import" href="../../../behaviors/base-url-behavior/base-url-behavior.html">
 | 
				
			||||||
<link rel="import" href="../../../behaviors/gr-change-table-behavior/gr-change-table-behavior.html">
 | 
					<link rel="import" href="../../../behaviors/gr-change-table-behavior/gr-change-table-behavior.html">
 | 
				
			||||||
 | 
					<link rel="import" href="../../../behaviors/gr-path-list-behavior/gr-path-list-behavior.html">
 | 
				
			||||||
<link rel="import" href="../../../behaviors/gr-url-encoding-behavior.html">
 | 
					<link rel="import" href="../../../behaviors/gr-url-encoding-behavior.html">
 | 
				
			||||||
<link rel="import" href="../../../behaviors/rest-client-behavior/rest-client-behavior.html">
 | 
					<link rel="import" href="../../../behaviors/rest-client-behavior/rest-client-behavior.html">
 | 
				
			||||||
<link rel="import" href="../../../bower_components/polymer/polymer.html">
 | 
					<link rel="import" href="../../../bower_components/polymer/polymer.html">
 | 
				
			||||||
@@ -148,7 +149,12 @@ limitations under the License.
 | 
				
			|||||||
    </td>
 | 
					    </td>
 | 
				
			||||||
    <td class="cell project"
 | 
					    <td class="cell project"
 | 
				
			||||||
        hidden$="[[isColumnHidden('Project', visibleChangeTableColumns)]]">
 | 
					        hidden$="[[isColumnHidden('Project', visibleChangeTableColumns)]]">
 | 
				
			||||||
      <a href$="[[_computeProjectURL(change.project)]]">[[change.project]]</a>
 | 
					      <a class="fullProject" href$="[[_computeProjectURL(change.project)]]">
 | 
				
			||||||
 | 
					        [[change.project]]
 | 
				
			||||||
 | 
					      </a>
 | 
				
			||||||
 | 
					      <a class="truncatedProject" href$="[[_computeProjectURL(change.project)]]">
 | 
				
			||||||
 | 
					        [[_computeTruncatedProject(change.project)]]
 | 
				
			||||||
 | 
					      </a>
 | 
				
			||||||
    </td>
 | 
					    </td>
 | 
				
			||||||
    <td class="cell branch"
 | 
					    <td class="cell branch"
 | 
				
			||||||
        hidden$="[[isColumnHidden('Branch', visibleChangeTableColumns)]]">
 | 
					        hidden$="[[isColumnHidden('Branch', visibleChangeTableColumns)]]">
 | 
				
			||||||
@@ -157,7 +163,7 @@ limitations under the License.
 | 
				
			|||||||
      </a>
 | 
					      </a>
 | 
				
			||||||
      <template is="dom-if" if="[[change.topic]]">
 | 
					      <template is="dom-if" if="[[change.topic]]">
 | 
				
			||||||
        (<a href$="[[_computeTopicURL(change)]]"><!--
 | 
					        (<a href$="[[_computeTopicURL(change)]]"><!--
 | 
				
			||||||
       --><gr-limited-text limit="30" text="[[change.topic]]">
 | 
					       --><gr-limited-text limit="50" text="[[change.topic]]">
 | 
				
			||||||
          </gr-limited-text><!--
 | 
					          </gr-limited-text><!--
 | 
				
			||||||
     --></a>)
 | 
					     --></a>)
 | 
				
			||||||
      </template>
 | 
					      </template>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -39,6 +39,7 @@
 | 
				
			|||||||
    behaviors: [
 | 
					    behaviors: [
 | 
				
			||||||
      Gerrit.BaseUrlBehavior,
 | 
					      Gerrit.BaseUrlBehavior,
 | 
				
			||||||
      Gerrit.ChangeTableBehavior,
 | 
					      Gerrit.ChangeTableBehavior,
 | 
				
			||||||
 | 
					      Gerrit.PathListBehavior,
 | 
				
			||||||
      Gerrit.RESTClientBehavior,
 | 
					      Gerrit.RESTClientBehavior,
 | 
				
			||||||
      Gerrit.URLEncodingBehavior,
 | 
					      Gerrit.URLEncodingBehavior,
 | 
				
			||||||
    ],
 | 
					    ],
 | 
				
			||||||
@@ -115,5 +116,10 @@
 | 
				
			|||||||
      if (!change.topic) { return ''; }
 | 
					      if (!change.topic) { return ''; }
 | 
				
			||||||
      return Gerrit.Nav.getUrlForTopic(change.topic);
 | 
					      return Gerrit.Nav.getUrlForTopic(change.topic);
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    _computeTruncatedProject(project) {
 | 
				
			||||||
 | 
					      if (!project) { return ''; }
 | 
				
			||||||
 | 
					      return this.truncatePath(project, 2);
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
  });
 | 
					  });
 | 
				
			||||||
})();
 | 
					})();
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -96,6 +96,24 @@ limitations under the License.
 | 
				
			|||||||
      .label:not(.topHeader) {
 | 
					      .label:not(.topHeader) {
 | 
				
			||||||
        border-left: 1px solid #ddd;
 | 
					        border-left: 1px solid #ddd;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
 | 
					      .truncatedProject {
 | 
				
			||||||
 | 
					        display: none;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      @media only screen and (max-width: 90em) {
 | 
				
			||||||
 | 
					        .assignee,
 | 
				
			||||||
 | 
					        .branch,
 | 
				
			||||||
 | 
					        .owner {
 | 
				
			||||||
 | 
					          overflow: hidden;
 | 
				
			||||||
 | 
					          max-width: 10rem;
 | 
				
			||||||
 | 
					          text-overflow: ellipsis;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        .truncatedProject {
 | 
				
			||||||
 | 
					          display: inline-block;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        .fullProject {
 | 
				
			||||||
 | 
					          display: none;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
      @media only screen and (max-width: 50em) {
 | 
					      @media only screen and (max-width: 50em) {
 | 
				
			||||||
        :host {
 | 
					        :host {
 | 
				
			||||||
          font-size: var(--font-size-large);
 | 
					          font-size: var(--font-size-large);
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user