Merge "Documentation: clarify what happens if you override a label in a child."
diff --git a/polygerrit-ui/app/elements/admin/gr-access-section/gr-access-section.html b/polygerrit-ui/app/elements/admin/gr-access-section/gr-access-section.html
index cf1102d..3779402 100644
--- a/polygerrit-ui/app/elements/admin/gr-access-section/gr-access-section.html
+++ b/polygerrit-ui/app/elements/admin/gr-access-section/gr-access-section.html
@@ -122,7 +122,8 @@
labels="[[labels]]"
section="[[section.id]]"
editing="[[editing]]"
- groups="[[groups]]">
+ groups="[[groups]]"
+ on-added-permission-removed="_handleAddedPermissionRemoved">
</gr-permission>
</template>
<div id="addPermission">
diff --git a/polygerrit-ui/app/elements/admin/gr-access-section/gr-access-section.js b/polygerrit-ui/app/elements/admin/gr-access-section/gr-access-section.js
index b6d2955..4574e11 100644
--- a/polygerrit-ui/app/elements/admin/gr-access-section/gr-access-section.js
+++ b/polygerrit-ui/app/elements/admin/gr-access-section/gr-access-section.js
@@ -23,6 +23,11 @@
* @event access-modified
*/
+ /**
+ * Fired when a section that was previously added was removed.
+ * @event added-section-removed
+ */
+
const GLOBAL_NAME = 'GLOBAL_CAPABILITIES';
// The name that gets automatically input when a new reference is added.
@@ -130,6 +135,12 @@
return section.id === 'GLOBAL_CAPABILITIES' ? 'hide' : '';
},
+ _handleAddedPermissionRemoved(e) {
+ const index = e.model.index;
+ this._permissions = this._permissions.slice(0, index).concat(
+ this._permissions.slice(index + 1, this._permissions.length));
+ },
+
_computeLabelOptions(labels) {
const labelOptions = [];
for (const labelName of Object.keys(labels)) {
@@ -184,6 +195,10 @@
},
_handleRemoveReference() {
+ if (this.section.value.added) {
+ this.dispatchEvent(new CustomEvent('added-section-removed',
+ {bubbles: true}));
+ }
this._deleted = true;
this.section.value.deleted = true;
this.dispatchEvent(new CustomEvent('access-modified', {bubbles: true}));
diff --git a/polygerrit-ui/app/elements/admin/gr-access-section/gr-access-section_test.html b/polygerrit-ui/app/elements/admin/gr-access-section/gr-access-section_test.html
index ea42101..ad401b8 100644
--- a/polygerrit-ui/app/elements/admin/gr-access-section/gr-access-section_test.html
+++ b/polygerrit-ui/app/elements/admin/gr-access-section/gr-access-section_test.html
@@ -507,6 +507,23 @@
assert.isFalse(element._deleted);
assert.isNotOk(element.section.value.deleted);
});
+
+ test('removing an added permission', () => {
+ element.editing = true;
+ assert.equal(element._permissions.length, 1);
+ element.$$('gr-permission').fire('added-permission-removed');
+ flushAsynchronousOperations();
+ assert.equal(element._permissions.length, 0);
+ });
+
+ test('remove an added section', () => {
+ const removeStub = sandbox.stub();
+ element.addEventListener('added-section-removed', removeStub);
+ element.editing = true;
+ element.section.value.added = true;
+ MockInteractions.tap(element.$.deleteBtn);
+ assert.isTrue(removeStub.called);
+ });
});
});
});
diff --git a/polygerrit-ui/app/elements/admin/gr-admin-view/gr-admin-view.html b/polygerrit-ui/app/elements/admin/gr-admin-view/gr-admin-view.html
index 3a54152c..3c9cdfb 100644
--- a/polygerrit-ui/app/elements/admin/gr-admin-view/gr-admin-view.html
+++ b/polygerrit-ui/app/elements/admin/gr-admin-view/gr-admin-view.html
@@ -24,6 +24,8 @@
<link rel="import" href="../../../styles/gr-page-nav-styles.html">
<link rel="import" href="../../../styles/shared-styles.html">
<link rel="import" href="../../core/gr-navigation/gr-navigation.html">
+<link rel="import" href="../../shared/gr-dropdown-list/gr-dropdown-list.html">
+<link rel="import" href="../../shared/gr-icons/gr-icons.html">
<link rel="import" href="../../shared/gr-js-api-interface/gr-js-api-interface.html">
<link rel="import" href="../../shared/gr-page-nav/gr-page-nav.html">
<link rel="import" href="../../shared/gr-rest-api-interface/gr-rest-api-interface.html">
@@ -43,7 +45,38 @@
<template>
<style include="shared-styles"></style>
<style include="gr-menu-page-styles"></style>
- <style include="gr-page-nav-styles"></style>
+ <style include="gr-page-nav-styles">
+ gr-dropdown-list {
+ --trigger-style: {
+ text-transform: none;
+ }
+ }
+ .breadcrumbText {
+ /* Same as dropdown trigger so chevron spacing is consistent. */
+ padding: 5px 4px;
+ }
+ iron-icon {
+ margin: 0 .2em;
+ }
+ .breadcrumb {
+ align-items: center;
+ display: flex;
+ }
+ .mainHeader {
+ align-items: baseline;
+ border-bottom: 1px solid var(--border-color);
+ display: flex;
+ }
+ .selectText {
+ display: none;
+ }
+ .selectText.show {
+ display: inline-block;
+ }
+ main.breadcrumbs:not(.table) {
+ margin-top: 1em;
+ }
+ </style>
<gr-page-nav class="navStyles">
<ul class="sectionContent">
<template id="adminNav" is="dom-repeat" items="[[_filteredLinks]]">
@@ -75,29 +108,26 @@
</template>
</ul>
</gr-page-nav>
+ <template is="dom-if" if="[[_subsectionLinks.length]]">
+ <section class="mainHeader">
+ <span class="breadcrumb">
+ <span class="breadcrumbText">[[_breadcrumbParentName]]</span>
+ <iron-icon icon="gr-icons:chevron-right"></iron-icon>
+ </span>
+ <gr-dropdown-list
+ lowercase
+ id="pageSelect"
+ value="[[_computeSelectValue(params)]]"
+ items="[[_subsectionLinks]]"
+ on-value-change="_handleSubsectionChange">
+ </gr-dropdown-list>
+ </section>
+ </template>
<template is="dom-if" if="[[_showRepoList]]" restamp="true">
<main class="table">
<gr-repo-list class="table" params="[[params]]"></gr-repo-list>
</main>
</template>
- <template is="dom-if" if="[[_showRepoMain]]" restamp="true">
- <main>
- <gr-repo repo="[[params.repo]]"></gr-repo>
- </main>
- </template>
- <template is="dom-if" if="[[_showGroup]]" restamp="true">
- <main>
- <gr-group
- group-id="[[params.groupId]]"
- on-name-changed="_updateGroupName"></gr-group>
- </main>
- </template>
- <template is="dom-if" if="[[_showGroupMembers]]" restamp="true">
- <main>
- <gr-group-members
- group-id="[[params.groupId]]"></gr-group-members>
- </main>
- </template>
<template is="dom-if" if="[[_showGroupList]]" restamp="true">
<main class="table">
<gr-admin-group-list class="table" params="[[params]]">
@@ -109,35 +139,53 @@
<gr-plugin-list class="table" params="[[params]]"></gr-plugin-list>
</main>
</template>
+ <template is="dom-if" if="[[_showRepoMain]]" restamp="true">
+ <main class="breadcrumbs">
+ <gr-repo repo="[[params.repo]]"></gr-repo>
+ </main>
+ </template>
+ <template is="dom-if" if="[[_showGroup]]" restamp="true">
+ <main class="breadcrumbs">
+ <gr-group
+ group-id="[[params.groupId]]"
+ on-name-changed="_updateGroupName"></gr-group>
+ </main>
+ </template>
+ <template is="dom-if" if="[[_showGroupMembers]]" restamp="true">
+ <main class="breadcrumbs">
+ <gr-group-members
+ group-id="[[params.groupId]]"></gr-group-members>
+ </main>
+ </template>
<template is="dom-if" if="[[_showRepoDetailList]]" restamp="true">
- <main class="table">
+ <main class="table breadcrumbs">
<gr-repo-detail-list
params="[[params]]"
class="table"></gr-repo-detail-list>
</main>
</template>
<template is="dom-if" if="[[_showGroupAuditLog]]" restamp="true">
- <main class="table">
+ <main class="table breadcrumbs">
<gr-group-audit-log
group-id="[[params.groupId]]"
class="table"></gr-group-audit-log>
</main>
</template>
<template is="dom-if" if="[[_showRepoCommands]]" restamp="true">
- <main>
+ <main class="breadcrumbs">
<gr-repo-commands
repo="[[params.repo]]"></gr-repo-commands>
</main>
</template>
<template is="dom-if" if="[[_showRepoAccess]]" restamp="true">
- <main class="table">
+ <main class="breadcrumbs">
<gr-repo-access
path="[[path]]"
repo="[[params.repo]]"></gr-repo-access>
</main>
</template>
<template is="dom-if" if="[[_showRepoDashboards]]" restamp="true">
- <main class="table">
+ <main class="table breadcrumbs">
<gr-repo-dashboards repo="[[params.repo]]"></gr-repo-dashboards>
</main>
</template>
diff --git a/polygerrit-ui/app/elements/admin/gr-admin-view/gr-admin-view.js b/polygerrit-ui/app/elements/admin/gr-admin-view/gr-admin-view.js
index f04fafb..3d430c2 100644
--- a/polygerrit-ui/app/elements/admin/gr-admin-view/gr-admin-view.js
+++ b/polygerrit-ui/app/elements/admin/gr-admin-view/gr-admin-view.js
@@ -29,6 +29,7 @@
path: String,
adminView: String,
+ _breadcrumbParentName: String,
_repoName: String,
_groupId: {
type: Number,
@@ -103,6 +104,8 @@
options)
.then(res => {
this._filteredLinks = res.links;
+ this._breadcrumbParentName = res.expandedSection ?
+ res.expandedSection.name : '';
if (!res.expandedSection) {
this._subsectionLinks = [];
@@ -112,7 +115,7 @@
.concat(res.expandedSection.children).map(section => {
return {
text: !section.detailType ? 'Home' : section.name,
- value: section.view + section.detailType,
+ value: section.view + (section.detailType || ''),
view: section.view,
url: section.url,
detailType: section.detailType,
@@ -123,6 +126,17 @@
});
},
+ _computeSelectValue(params) {
+ if (!params || !params.view) { return; }
+ return params.view + (params.detail || '');
+ },
+
+ _selectedIsCurrentPage(selected) {
+ return (selected.parent === (this._repoName || this._groupId) &&
+ selected.view === this.params.view &&
+ selected.detailType === this.params.detail);
+ },
+
_handleSubsectionChange(e) {
const selected = this._subsectionLinks
.find(section => section.value === e.detail.value);
@@ -165,16 +179,22 @@
this.set('_showPluginList', isAdminView &&
params.adminView === 'gr-plugin-list');
+ let needsReload = false;
if (params.repo !== this._repoName) {
this._repoName = params.repo || '';
// Reloads the admin menu.
- this.reload();
+ needsReload = true;
}
if (params.groupId !== this._groupId) {
this._groupId = params.groupId || '';
// Reloads the admin menu.
- this.reload();
+ needsReload = true;
}
+ if (this._breadcrumbParentName && !params.groupId && !params.repo) {
+ needsReload = true;
+ }
+ if (!needsReload) { return; }
+ this.reload();
},
_computeSelectedTitle(params) {
diff --git a/polygerrit-ui/app/elements/admin/gr-admin-view/gr-admin-view_test.html b/polygerrit-ui/app/elements/admin/gr-admin-view/gr-admin-view_test.html
index facfad5f..678fb99 100644
--- a/polygerrit-ui/app/elements/admin/gr-admin-view/gr-admin-view_test.html
+++ b/polygerrit-ui/app/elements/admin/gr-admin-view/gr-admin-view_test.html
@@ -79,7 +79,6 @@
name: 'Repositories',
url: '/admin/repos',
view: 'gr-repo-list',
- children: [],
}];
element.params = {
@@ -189,17 +188,10 @@
});
element.reload().then(() => {
flushAsynchronousOperations();
- assert.equal(element._filteredLinks.length, 3);
-
- // Repos
- assert.equal(element._filteredLinks[0].subsection.children.length, 5);
- assert.equal(element._filteredLinks[0].subsection.name, 'Test Repo');
-
- // Groups
- assert.isNotOk(element._filteredLinks[1].subsection);
-
- // Plugins
- assert.isNotOk(element._filteredLinks[2].subsection);
+ assert.equal(Polymer.dom(element.root)
+ .querySelectorAll('.sectionTitle').length, 3);
+ assert.equal(element.$$('.breadcrumbText').innerText, 'Test Repo');
+ assert.equal(element.$$('#pageSelect').items.length, 6);
done();
});
});
@@ -287,6 +279,188 @@
element.$$('gr-group').fire('name-changed', {name: newName});
});
+ test('dropdown displays if there is a subsection', () => {
+ assert.isNotOk(element.$$('.mainHeader'));
+ element._subsectionLinks = [
+ {
+ text: 'Home',
+ value: 'repo',
+ view: 'repo',
+ url: '',
+ parent: 'my-repo',
+ detailType: undefined,
+ },
+ ];
+ flushAsynchronousOperations();
+ assert.isOk(element.$$('.mainHeader'));
+ element._subsectionLinks = undefined;
+ flushAsynchronousOperations();
+ assert.equal(getComputedStyle(element.$$('.mainHeader')).display, 'none');
+ });
+
+ test('Dropdown only triggers navigation on explicit select', done => {
+ element._repoName = 'my-repo';
+ element.params = {
+ repo: 'my-repo',
+ view: Gerrit.Nav.View.REPO,
+ detail: Gerrit.Nav.RepoDetailView.ACCESS,
+ };
+ sandbox.stub(element.$.restAPI, 'getAccountCapabilities', () => {
+ return Promise.resolve({
+ createGroup: true,
+ createProject: true,
+ viewPlugins: true,
+ });
+ });
+ sandbox.stub(element.$.restAPI, 'getAccount', () => {
+ return Promise.resolve({_id: 1});
+ });
+ flushAsynchronousOperations();
+ const expectedFilteredLinks = [
+ {
+ name: 'Repositories',
+ noBaseUrl: true,
+ url: '/admin/repos',
+ view: 'gr-repo-list',
+ viewableToAll: true,
+ subsection: {
+ name: 'my-repo',
+ view: 'repo',
+ url: '',
+ children: [
+ {
+ name: 'Access',
+ view: 'repo',
+ detailType: 'access',
+ url: '',
+ },
+ {
+ name: 'Commands',
+ view: 'repo',
+ detailType: 'commands',
+ url: '',
+ },
+ {
+ name: 'Branches',
+ view: 'repo',
+ detailType: 'branches',
+ url: '',
+ },
+ {
+ name: 'Tags',
+ view: 'repo',
+ detailType: 'tags',
+ url: '',
+ },
+ {
+ name: 'Dashboards',
+ view: 'repo',
+ detailType: 'dashboards',
+ url: '',
+ },
+ ],
+ },
+ },
+ {
+ name: 'Groups',
+ section: 'Groups',
+ noBaseUrl: true,
+ url: '/admin/groups',
+ view: 'gr-admin-group-list',
+ },
+ {
+ name: 'Plugins',
+ capability: 'viewPlugins',
+ section: 'Plugins',
+ noBaseUrl: true,
+ url: '/admin/plugins',
+ view: 'gr-plugin-list',
+ },
+ ];
+ const expectedSubsectionLinks = [
+ {
+ text: 'Home',
+ value: 'repo',
+ view: 'repo',
+ url: '',
+ parent: 'my-repo',
+ detailType: undefined,
+ },
+ {
+ text: 'Access',
+ value: 'repoaccess',
+ view: 'repo',
+ url: '',
+ detailType: 'access',
+ parent: 'my-repo',
+ },
+ {
+ text: 'Commands',
+ value: 'repocommands',
+ view: 'repo',
+ url: '',
+ detailType: 'commands',
+ parent: 'my-repo',
+ },
+ {
+ text: 'Branches',
+ value: 'repobranches',
+ view: 'repo',
+ url: '',
+ detailType: 'branches',
+ parent: 'my-repo',
+ },
+ {
+ text: 'Tags',
+ value: 'repotags',
+ view: 'repo',
+ url: '',
+ detailType: 'tags',
+ parent: 'my-repo',
+ },
+ {
+ text: 'Dashboards',
+ value: 'repodashboards',
+ view: 'repo',
+ url: '',
+ detailType: 'dashboards',
+ parent: 'my-repo',
+ },
+ ];
+ sandbox.stub(Gerrit.Nav, 'navigateToRelativeUrl');
+ sandbox.spy(element, '_selectedIsCurrentPage');
+ sandbox.spy(element, '_handleSubsectionChange');
+ element.reload().then(() => {
+ assert.deepEqual(element._filteredLinks, expectedFilteredLinks);
+ assert.deepEqual(element._subsectionLinks, expectedSubsectionLinks);
+ assert.equal(element.$$('#pageSelect').value, 'repoaccess');
+ assert.isTrue(element._selectedIsCurrentPage.calledOnce);
+ // Doesn't trigger navigation from the page select menu.
+ assert.isFalse(Gerrit.Nav.navigateToRelativeUrl.called);
+
+ // When explicitly changed, navigation is called
+ element.$$('#pageSelect').value = 'repo';
+ assert.isTrue(element._selectedIsCurrentPage.calledTwice);
+ assert.isTrue(Gerrit.Nav.navigateToRelativeUrl.calledOnce);
+ done();
+ });
+ });
+
+ test('_selectedIsCurrentPage', () => {
+ element._repoName = 'my-repo';
+ element.params = {view: 'repo', repo: 'my-repo'};
+ const selected = {
+ view: 'repo',
+ detailType: undefined,
+ parent: 'my-repo',
+ };
+ assert.isTrue(element._selectedIsCurrentPage(selected));
+ selected.parent = 'my-second-repo';
+ assert.isFalse(element._selectedIsCurrentPage(selected));
+ selected.detailType = 'detailType';
+ assert.isFalse(element._selectedIsCurrentPage(selected));
+ });
+
suite('_computeSelectedClass', () => {
setup(() => {
sandbox.stub(element.$.restAPI, 'getAccountCapabilities', () => {
diff --git a/polygerrit-ui/app/elements/admin/gr-permission/gr-permission.html b/polygerrit-ui/app/elements/admin/gr-permission/gr-permission.html
index 4a3bbc9..22f461b 100644
--- a/polygerrit-ui/app/elements/admin/gr-permission/gr-permission.html
+++ b/polygerrit-ui/app/elements/admin/gr-permission/gr-permission.html
@@ -115,7 +115,8 @@
group-name="[[_computeGroupName(groups, rule.id)]]"
permission="[[permission.id]]"
rule="{{rule}}"
- section="[[section]]"></gr-rule-editor>
+ section="[[section]]"
+ on-added-rule-removed="_handleAddedRuleRemoved"></gr-rule-editor>
</template>
<div id="addRule">
<gr-autocomplete
diff --git a/polygerrit-ui/app/elements/admin/gr-permission/gr-permission.js b/polygerrit-ui/app/elements/admin/gr-permission/gr-permission.js
index 01caf1d..31d371d 100644
--- a/polygerrit-ui/app/elements/admin/gr-permission/gr-permission.js
+++ b/polygerrit-ui/app/elements/admin/gr-permission/gr-permission.js
@@ -25,6 +25,11 @@
* @event access-modified
*/
+ /**
+ * Fired when a permission that was previously added was removed.
+ * @event added-permission-removed
+ */
+
Polymer({
is: 'gr-permission',
@@ -117,6 +122,12 @@
}
},
+ _handleAddedRuleRemoved(e) {
+ const index = e.model.index;
+ this._rules = this._rules.slice(0, index)
+ .concat(this._rules.slice(index + 1, this._rules.length));
+ },
+
_handleValueChange() {
this.permission.value.modified = true;
// Allows overall access page to know a change has been made.
@@ -124,6 +135,10 @@
},
_handleRemovePermission() {
+ if (this.permission.value.added) {
+ this.dispatchEvent(new CustomEvent('added-permission-removed',
+ {bubbles: true}));
+ }
this._deleted = true;
this.permission.value.deleted = true;
this.dispatchEvent(new CustomEvent('access-modified', {bubbles: true}));
diff --git a/polygerrit-ui/app/elements/admin/gr-permission/gr-permission_test.html b/polygerrit-ui/app/elements/admin/gr-permission/gr-permission_test.html
index 6799d10..e29c4a2 100644
--- a/polygerrit-ui/app/elements/admin/gr-permission/gr-permission_test.html
+++ b/polygerrit-ui/app/elements/admin/gr-permission/gr-permission_test.html
@@ -327,11 +327,36 @@
assert.equal(Object.keys(element.permission.value.rules).length, 2);
});
+ test('removing an added rule', () => {
+ element.name = 'Priority';
+ element.section = 'refs/*';
+ element.groups = {};
+ element.$.groupAutocomplete.text = 'new group name';
+ assert.equal(element._rules.length, 2);
+ element.$$('gr-rule-editor').fire('added-rule-removed');
+ flushAsynchronousOperations();
+ assert.equal(element._rules.length, 1);
+ });
+
+ test('removing an added permission', () => {
+ const removeStub = sandbox.stub();
+ element.addEventListener('added-permission-removed', removeStub);
+ element.editing = true;
+ element.name = 'Priority';
+ element.section = 'refs/*';
+ element.permission.value.added = true;
+ MockInteractions.tap(element.$.removeBtn);
+ assert.isTrue(removeStub.called);
+ });
+
test('removing the permission', () => {
element.editing = true;
element.name = 'Priority';
element.section = 'refs/*';
+ const removeStub = sandbox.stub();
+ element.addEventListener('added-permission-removed', removeStub);
+
assert.isFalse(element.$.permission.classList.contains('deleted'));
assert.isFalse(element._deleted);
MockInteractions.tap(element.$.removeBtn);
@@ -340,6 +365,7 @@
MockInteractions.tap(element.$.undoRemoveBtn);
assert.isFalse(element.$.permission.classList.contains('deleted'));
assert.isFalse(element._deleted);
+ assert.isFalse(removeStub.called);
});
test('modify a permission', () => {
diff --git a/polygerrit-ui/app/elements/admin/gr-repo-access/gr-repo-access.html b/polygerrit-ui/app/elements/admin/gr-repo-access/gr-repo-access.html
index acaf6dd..0ceac7c 100644
--- a/polygerrit-ui/app/elements/admin/gr-repo-access/gr-repo-access.html
+++ b/polygerrit-ui/app/elements/admin/gr-repo-access/gr-repo-access.html
@@ -111,7 +111,8 @@
section="{{section}}"
labels="[[_labels]]"
editing="[[_editing]]"
- groups="[[_groups]]"></gr-access-section>
+ groups="[[_groups]]"
+ on-added-section-removed="_handleAddedSectionRemoved"></gr-access-section>
</template>
<div class="referenceContainer">
<gr-button id="addReferenceBtn"
diff --git a/polygerrit-ui/app/elements/admin/gr-repo-access/gr-repo-access.js b/polygerrit-ui/app/elements/admin/gr-repo-access/gr-repo-access.js
index 853e316..f307090 100644
--- a/polygerrit-ui/app/elements/admin/gr-repo-access/gr-repo-access.js
+++ b/polygerrit-ui/app/elements/admin/gr-repo-access/gr-repo-access.js
@@ -243,6 +243,12 @@
return inheritsFrom ? 'show' : '';
},
+ _handleAddedSectionRemoved(e) {
+ const index = e.model.index;
+ this._sections = this._sections.slice(0, index)
+ .concat(this._sections.slice(index + 1, this._sections.length));
+ },
+
_handleEditingChanged(editing, editingOld) {
// Ignore when editing gets set initially.
if (!editingOld || editing) { return; }
diff --git a/polygerrit-ui/app/elements/admin/gr-repo-access/gr-repo-access_test.html b/polygerrit-ui/app/elements/admin/gr-repo-access/gr-repo-access_test.html
index 66fece3..2f0b1b8 100644
--- a/polygerrit-ui/app/elements/admin/gr-repo-access/gr-repo-access_test.html
+++ b/polygerrit-ui/app/elements/admin/gr-repo-access/gr-repo-access_test.html
@@ -301,6 +301,14 @@
flushAsynchronousOperations();
});
+ test('removing an added section', () => {
+ element.editing = true;
+ assert.equal(element._sections.length, 1);
+ element.$$('gr-access-section').fire('added-section-removed');
+ flushAsynchronousOperations();
+ assert.equal(element._sections.length, 0);
+ });
+
test('button visibility for non admin', () => {
assert.equal(getComputedStyle(element.$.saveBtn).display, 'none');
assert.equal(getComputedStyle(element.$.editBtn).display, 'none');
diff --git a/polygerrit-ui/app/elements/admin/gr-rule-editor/gr-rule-editor.js b/polygerrit-ui/app/elements/admin/gr-rule-editor/gr-rule-editor.js
index d4c5fd1..503811d 100644
--- a/polygerrit-ui/app/elements/admin/gr-rule-editor/gr-rule-editor.js
+++ b/polygerrit-ui/app/elements/admin/gr-rule-editor/gr-rule-editor.js
@@ -23,6 +23,11 @@
* @event access-modified
*/
+ /**
+ * Fired when a rule that was previously added was removed.
+ * @event added-rule-removed
+ */
+
const PRIORITY_OPTIONS = [
'BATCH',
'INTERACTIVE',
@@ -202,6 +207,10 @@
},
_handleRemoveRule() {
+ if (this.rule.value.added) {
+ this.dispatchEvent(new CustomEvent('added-rule-removed',
+ {bubbles: true}));
+ }
this._deleted = true;
this.rule.value.deleted = true;
this.dispatchEvent(new CustomEvent('access-modified', {bubbles: true}));
diff --git a/polygerrit-ui/app/elements/admin/gr-rule-editor/gr-rule-editor_test.html b/polygerrit-ui/app/elements/admin/gr-rule-editor/gr-rule-editor_test.html
index 3e3bcfb..666a8f6 100644
--- a/polygerrit-ui/app/elements/admin/gr-rule-editor/gr-rule-editor_test.html
+++ b/polygerrit-ui/app/elements/admin/gr-rule-editor/gr-rule-editor_test.html
@@ -319,6 +319,7 @@
element.section = 'refs/*';
element._setupValues(element.rule);
flushAsynchronousOperations();
+ element.rule.value.added = true;
});
test('_ruleValues and _originalRuleValues are set correctly', () => {
@@ -328,9 +329,9 @@
const expectedRuleValue = {
action: 'ALLOW',
force: false,
+ added: true,
};
assert.deepEqual(element.rule.value, expectedRuleValue);
- assert.deepEqual(element._originalRuleValues, expectedRuleValue);
test('values are set correctly', () => {
assert.equal(element.$.action.bindValue, expectedRuleValue.action);
assert.equal(element.$.force.bindValue, expectedRuleValue.action);
@@ -346,6 +347,15 @@
// The original value should now differ from the rule values.
assert.notDeepEqual(element._originalRuleValues, element.rule.value);
});
+
+ test('remove value', () => {
+ element.editing = true;
+ const removeStub = sandbox.stub();
+ element.addEventListener('added-rule-removed', removeStub);
+ MockInteractions.tap(element.$.removeBtn);
+ flushAsynchronousOperations();
+ assert.isTrue(removeStub.called);
+ });
});
suite('already existing rule with labels', () => {
@@ -389,10 +399,13 @@
});
test('modify value', () => {
+ const removeStub = sandbox.stub();
+ element.addEventListener('added-rule-removed', removeStub);
assert.isNotOk(element.rule.value.modified);
Polymer.dom(element.root).querySelector('#labelMin').bindValue = 1;
flushAsynchronousOperations();
assert.isTrue(element.rule.value.modified);
+ assert.isFalse(removeStub.called);
// The original value should now differ from the rule values.
assert.notDeepEqual(element._originalRuleValues, element.rule.value);
@@ -417,6 +430,7 @@
element.section = 'refs/*';
element._setupValues(element.rule);
flushAsynchronousOperations();
+ element.rule.value.added = true;
});
test('_ruleValues and _originalRuleValues are set correctly', () => {
@@ -429,9 +443,9 @@
max: element.label.values[element.label.values.length - 1].value,
min: element.label.values[0].value,
action: 'ALLOW',
+ added: true,
};
assert.deepEqual(element.rule.value, expectedRuleValue);
- assert.deepEqual(element._originalRuleValues, expectedRuleValue);
test('values are set correctly', () => {
assert.equal(
element.$.action.bindValue,
@@ -507,6 +521,7 @@
element.section = 'refs/*';
element._setupValues(element.rule);
flushAsynchronousOperations();
+ element.rule.value.added = true;
});
test('_ruleValues and _originalRuleValues are set correctly', () => {
@@ -516,9 +531,9 @@
const expectedRuleValue = {
action: 'ALLOW',
force: false,
+ added: true,
};
assert.deepEqual(element.rule.value, expectedRuleValue);
- assert.deepEqual(element._originalRuleValues, expectedRuleValue);
test('values are set correctly', () => {
assert.equal(element.$.action.bindValue, expectedRuleValue.action);
assert.equal(element.$.force.bindValue, expectedRuleValue.action);
@@ -576,44 +591,5 @@
assert.notDeepEqual(element._originalRuleValues, element.rule.value);
});
});
-
- suite('new edit rule', () => {
- setup(() => {
- element.group = 'Group Name';
- element.permission = 'editTopicName';
- element.rule = {
- id: '123',
- };
- element.section = 'refs/*';
- element._setupValues(element.rule);
- flushAsynchronousOperations();
- });
-
- test('_ruleValues and _originalRuleValues are set correctly', () => {
- // Since the element does not already have default values, they should
- // be set. The original values should be set to those too.
- assert.isNotOk(element.rule.value.modified);
- const expectedRuleValue = {
- action: 'ALLOW',
- force: false,
- };
- assert.deepEqual(element.rule.value, expectedRuleValue);
- assert.deepEqual(element._originalRuleValues, expectedRuleValue);
- test('values are set correctly', () => {
- assert.equal(element.$.action.bindValue, expectedRuleValue.action);
- assert.equal(element.$.force.bindValue, expectedRuleValue.action);
- });
- });
-
- test('modify value', () => {
- assert.isNotOk(element.rule.value.modified);
- element.$.force.bindValue = true;
- flushAsynchronousOperations();
- assert.isTrue(element.rule.value.modified);
-
- // The original value should now differ from the rule values.
- assert.notDeepEqual(element._originalRuleValues, element.rule.value);
- });
- });
});
</script>
diff --git a/polygerrit-ui/app/elements/change-list/gr-dashboard-view/gr-dashboard-view.html b/polygerrit-ui/app/elements/change-list/gr-dashboard-view/gr-dashboard-view.html
index 101899b..1935962 100644
--- a/polygerrit-ui/app/elements/change-list/gr-dashboard-view/gr-dashboard-view.html
+++ b/polygerrit-ui/app/elements/change-list/gr-dashboard-view/gr-dashboard-view.html
@@ -15,10 +15,11 @@
limitations under the License.
-->
-<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="../../../behaviors/rest-client-behavior/rest-client-behavior.html">
<link rel="import" href="../../../styles/shared-styles.html">
<link rel="import" href="../../change-list/gr-change-list/gr-change-list.html">
+<link rel="import" href="../../core/gr-reporting/gr-reporting.html">
<link rel="import" href="../../shared/gr-rest-api-interface/gr-rest-api-interface.html">
<link rel="import" href="../gr-user-header/gr-user-header.html">
@@ -62,6 +63,7 @@
sections="[[_results]]"></gr-change-list>
</div>
<gr-rest-api-interface id="restAPI"></gr-rest-api-interface>
+ <gr-reporting id="reporting"></gr-reporting>
</template>
<script src="gr-dashboard-view.js"></script>
</dom-module>
diff --git a/polygerrit-ui/app/elements/change-list/gr-dashboard-view/gr-dashboard-view.js b/polygerrit-ui/app/elements/change-list/gr-dashboard-view/gr-dashboard-view.js
index b6e06d8..f86c98c 100644
--- a/polygerrit-ui/app/elements/change-list/gr-dashboard-view/gr-dashboard-view.js
+++ b/polygerrit-ui/app/elements/change-list/gr-dashboard-view/gr-dashboard-view.js
@@ -230,6 +230,8 @@
};
});
});
+ }).then(() => {
+ this.$.reporting.dashboardDisplayed();
}).catch(err => {
this._loading = false;
console.warn(err);
diff --git a/polygerrit-ui/app/elements/change-list/gr-dashboard-view/gr-dashboard-view_test.html b/polygerrit-ui/app/elements/change-list/gr-dashboard-view/gr-dashboard-view_test.html
index a3aa4f2..a1da018 100644
--- a/polygerrit-ui/app/elements/change-list/gr-dashboard-view/gr-dashboard-view_test.html
+++ b/polygerrit-ui/app/elements/change-list/gr-dashboard-view/gr-dashboard-view_test.html
@@ -55,7 +55,7 @@
});
const paramsChanged = element._paramsChanged.bind(element);
sandbox.stub(element, '_paramsChanged', params => {
- paramsChanged(params).then(resolver());
+ paramsChanged(params).then(() => resolver());
});
});
@@ -262,5 +262,17 @@
dashboard: 'dashboard',
};
});
+
+ test('params change triggers dashboardDisplayed()', () => {
+ sandbox.stub(element.$.reporting, 'dashboardDisplayed');
+ element.params = {
+ view: Gerrit.Nav.View.DASHBOARD,
+ project: 'project',
+ dashboard: 'dashboard',
+ };
+ return paramsChangedPromise.then(() => {
+ assert.isTrue(element.$.reporting.dashboardDisplayed.calledOnce);
+ });
+ });
});
</script>
diff --git a/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view.html b/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view.html
index 88cee4c..0688435 100644
--- a/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view.html
+++ b/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view.html
@@ -22,6 +22,7 @@
<link rel="import" href="../../../bower_components/paper-tabs/paper-tabs.html">
<link rel="import" href="../../../styles/shared-styles.html">
<link rel="import" href="../../core/gr-navigation/gr-navigation.html">
+<link rel="import" href="../../core/gr-reporting/gr-reporting.html">
<link rel="import" href="../../diff/gr-comment-api/gr-comment-api.html">
<link rel="import" href="../../diff/gr-diff-preferences/gr-diff-preferences.html">
<link rel="import" href="../../edit/gr-edit-constants.html">
@@ -615,6 +616,7 @@
<gr-js-api-interface id="jsAPI"></gr-js-api-interface>
<gr-rest-api-interface id="restAPI"></gr-rest-api-interface>
<gr-comment-api id="commentAPI"></gr-comment-api>
+ <gr-reporting id="reporting"></gr-reporting>
</template>
<script src="gr-change-view.js"></script>
</dom-module>
diff --git a/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view.js b/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view.js
index 7b31ee3..29ffec8 100644
--- a/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view.js
+++ b/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view.js
@@ -1210,8 +1210,10 @@
this._reloadComments();
+ let reloadPromise;
+
if (this._patchRange.patchNum) {
- return Promise.all([
+ reloadPromise = Promise.all([
this._reloadPatchNumDependentResources(),
detailCompletes,
]).then(() => {
@@ -1222,7 +1224,7 @@
});
} else {
// The patch number is reliant on the change detail request.
- return detailCompletes.then(() => {
+ reloadPromise = detailCompletes.then(() => {
this.$.fileList.reload();
if (!this._latestCommitMessage) {
this._getLatestCommitMessage();
@@ -1230,6 +1232,10 @@
return this._getMergeability();
});
}
+
+ return reloadPromise.then(() => {
+ this.$.reporting.changeDisplayed();
+ });
},
/**
diff --git a/polygerrit-ui/app/elements/core/gr-reporting/gr-reporting.js b/polygerrit-ui/app/elements/core/gr-reporting/gr-reporting.js
index e488961..73a29a7 100644
--- a/polygerrit-ui/app/elements/core/gr-reporting/gr-reporting.js
+++ b/polygerrit-ui/app/elements/core/gr-reporting/gr-reporting.js
@@ -38,6 +38,25 @@
CATEGORY: 'exception',
};
+ const TIMER = {
+ CHANGE_DISPLAYED: 'ChangeDisplayed',
+ DASHBOARD_DISPLAYED: 'DashboardDisplayed',
+ DIFF_VIEW_DISPLAYED: 'DiffViewDisplayed',
+ PLUGINS_LOADED: 'PluginsLoaded',
+ STARTUP_CHANGE_DISPLAYED: 'StartupChangeDisplayed',
+ STARTUP_DASHBOARD_DISPLAYED: 'StartupDashboardDisplayed',
+ STARTUP_DIFF_VIEW_DISPLAYED: 'StartupDiffViewDisplayed',
+ WEB_COMPONENTS_READY: 'WebComponentsReady',
+ };
+
+ const STARTUP_TIMERS = {};
+ STARTUP_TIMERS[TIMER.PLUGINS_LOADED] = 0;
+ STARTUP_TIMERS[TIMER.STARTUP_CHANGE_DISPLAYED] = 0;
+ STARTUP_TIMERS[TIMER.STARTUP_DASHBOARD_DISPLAYED] = 0;
+ STARTUP_TIMERS[TIMER.STARTUP_DIFF_VIEW_DISPLAYED] = 0;
+ // WebComponentsReady timer is triggered from gr-router.
+ STARTUP_TIMERS[TIMER.WEB_COMPONENTS_READY] = 0;
+
const INTERACTION_TYPE = 'interaction';
const pending = [];
@@ -81,8 +100,8 @@
category: String,
_baselines: {
- type: Array,
- value() { return {}; },
+ type: Object,
+ value: STARTUP_TIMERS, // Shared across all instances.
},
},
@@ -91,7 +110,7 @@
},
now() {
- return Math.round(10 * window.performance.now()) / 10;
+ return window.performance.now();
},
reporter(...args) {
@@ -157,13 +176,46 @@
}
},
+ beforeLocationChanged() {
+ for (const prop of Object.keys(this._baselines)) {
+ delete this._baselines[prop];
+ }
+ this.time(TIMER.CHANGE_DISPLAYED);
+ this.time(TIMER.DASHBOARD_DISPLAYED);
+ this.time(TIMER.DIFF_VIEW_DISPLAYED);
+ },
+
locationChanged(page) {
this.reporter(
NAVIGATION.TYPE, NAVIGATION.CATEGORY, NAVIGATION.PAGE, page);
},
+ dashboardDisplayed() {
+ if (this._baselines.hasOwnProperty(TIMER.STARTUP_DASHBOARD_DISPLAYED)) {
+ this.timeEnd(TIMER.STARTUP_DASHBOARD_DISPLAYED);
+ } else {
+ this.timeEnd(TIMER.DASHBOARD_DISPLAYED);
+ }
+ },
+
+ changeDisplayed() {
+ if (this._baselines.hasOwnProperty(TIMER.STARTUP_CHANGE_DISPLAYED)) {
+ this.timeEnd(TIMER.STARTUP_CHANGE_DISPLAYED);
+ } else {
+ this.timeEnd(TIMER.CHANGE_DISPLAYED);
+ }
+ },
+
+ diffViewDisplayed() {
+ if (this._baselines.hasOwnProperty(TIMER.STARTUP_DIFF_VIEW_DISPLAYED)) {
+ this.timeEnd(TIMER.STARTUP_DIFF_VIEW_DISPLAYED);
+ } else {
+ this.timeEnd(TIMER.DIFF_VIEW_DISPLAYED);
+ }
+ },
+
pluginsLoaded() {
- this.timeEnd('PluginsLoaded');
+ this.timeEnd(TIMER.PLUGINS_LOADED);
},
/**
@@ -177,7 +229,8 @@
* Finish named timer and report it to server.
*/
timeEnd(name) {
- const baseTime = this._baselines[name] || 0;
+ if (!this._baselines.hasOwnProperty(name)) { return; }
+ const baseTime = this._baselines[name];
const time = Math.round(this.now() - baseTime);
this.reporter(TIMING.TYPE, TIMING.CATEGORY, name, time);
delete this._baselines[name];
@@ -191,4 +244,5 @@
window.GrReporting = GrReporting;
// Expose onerror installation so it would be accessible from tests.
window.GrReporting._catchErrors = catchErrors;
+ window.GrReporting.STARTUP_TIMERS = Object.assign({}, STARTUP_TIMERS);
})();
diff --git a/polygerrit-ui/app/elements/core/gr-reporting/gr-reporting_test.html b/polygerrit-ui/app/elements/core/gr-reporting/gr-reporting_test.html
index 8a94e99..3965c7d 100644
--- a/polygerrit-ui/app/elements/core/gr-reporting/gr-reporting_test.html
+++ b/polygerrit-ui/app/elements/core/gr-reporting/gr-reporting_test.html
@@ -45,6 +45,7 @@
sandbox = sinon.sandbox.create();
clock = sinon.useFakeTimers(NOW_TIME);
element = fixture('basic');
+ element._baselines = Object.assign({}, GrReporting.STARTUP_TIMERS);
fakePerformance = {
navigationStart: 1,
loadEventEnd: 2,
@@ -53,6 +54,7 @@
{get() { return fakePerformance; }});
sandbox.stub(element, 'reporter');
});
+
teardown(() => {
sandbox.restore();
clock.restore();
@@ -67,6 +69,14 @@
));
});
+ test('WebComponentsReady', () => {
+ sandbox.stub(element, 'now').returns(42);
+ element.timeEnd('WebComponentsReady');
+ assert.isTrue(element.reporter.calledWithExactly(
+ 'timing-report', 'UI Latency', 'WebComponentsReady', 42
+ ));
+ });
+
test('pageLoaded', () => {
element.pageLoaded();
assert.isTrue(
@@ -76,6 +86,49 @@
);
});
+ test('beforeLocationChanged', () => {
+ element._baselines['garbage'] = 'monster';
+ sandbox.stub(element, 'time');
+ element.beforeLocationChanged();
+ assert.isTrue(element.time.calledWithExactly('DashboardDisplayed'));
+ assert.isTrue(element.time.calledWithExactly('ChangeDisplayed'));
+ assert.isTrue(element.time.calledWithExactly('DiffViewDisplayed'));
+ assert.isFalse(element._baselines.hasOwnProperty('garbage'));
+ });
+
+ test('changeDisplayed', () => {
+ sandbox.spy(element, 'timeEnd');
+ element.changeDisplayed();
+ assert.isFalse(
+ element.timeEnd.calledWithExactly('ChangeDisplayed'));
+ assert.isTrue(
+ element.timeEnd.calledWithExactly('StartupChangeDisplayed'));
+ element.changeDisplayed();
+ assert.isTrue(element.timeEnd.calledWithExactly('ChangeDisplayed'));
+ });
+
+ test('diffViewDisplayed', () => {
+ sandbox.spy(element, 'timeEnd');
+ element.diffViewDisplayed();
+ assert.isFalse(
+ element.timeEnd.calledWithExactly('DiffViewDisplayed'));
+ assert.isTrue(
+ element.timeEnd.calledWithExactly('StartupDiffViewDisplayed'));
+ element.diffViewDisplayed();
+ assert.isTrue(element.timeEnd.calledWithExactly('DiffViewDisplayed'));
+ });
+
+ test('dashboardDisplayed', () => {
+ sandbox.spy(element, 'timeEnd');
+ element.dashboardDisplayed();
+ assert.isFalse(
+ element.timeEnd.calledWithExactly('DashboardDisplayed'));
+ assert.isTrue(
+ element.timeEnd.calledWithExactly('StartupDashboardDisplayed'));
+ element.dashboardDisplayed();
+ assert.isTrue(element.timeEnd.calledWithExactly('DashboardDisplayed'));
+ });
+
test('time and timeEnd', () => {
const nowStub = sandbox.stub(element, 'now').returns(0);
element.time('foo');
@@ -117,11 +170,13 @@
test('reports if plugins are loaded', () => {
Gerrit._arePluginsLoaded.returns(true);
- element.timeEnd('foo');
+ element.pluginsLoaded();
assert.isTrue(element.defaultReporter.called);
});
test('reports cached events preserving order', () => {
+ element.time('foo');
+ element.time('bar');
Gerrit._arePluginsLoaded.returns(false);
element.timeEnd('foo');
Gerrit._arePluginsLoaded.returns(true);
diff --git a/polygerrit-ui/app/elements/core/gr-router/gr-router.js b/polygerrit-ui/app/elements/core/gr-router/gr-router.js
index 36648ab..8af7301 100644
--- a/polygerrit-ui/app/elements/core/gr-router/gr-router.js
+++ b/polygerrit-ui/app/elements/core/gr-router/gr-router.js
@@ -199,6 +199,7 @@
type: Object,
value: app,
},
+ _isRedirecting: Boolean,
},
behaviors: [
@@ -217,6 +218,7 @@
},
_redirect(url) {
+ this._isRedirecting = true;
page.redirect(url);
},
@@ -670,6 +672,14 @@
params => this._generateWeblinks(params)
);
+ page.exit('*', (ctx, next) => {
+ if (!this._isRedirecting) {
+ this.$.reporting.beforeLocationChanged();
+ }
+ this._isRedirecting = false;
+ next();
+ });
+
// Middleware
page((ctx, next) => {
document.body.scrollTop = 0;
diff --git a/polygerrit-ui/app/elements/diff/gr-diff-view/gr-diff-view.html b/polygerrit-ui/app/elements/diff/gr-diff-view/gr-diff-view.html
index df3a2c5..1fc99b1 100644
--- a/polygerrit-ui/app/elements/diff/gr-diff-view/gr-diff-view.html
+++ b/polygerrit-ui/app/elements/diff/gr-diff-view/gr-diff-view.html
@@ -23,6 +23,7 @@
<link rel="import" href="../../../bower_components/iron-dropdown/iron-dropdown.html">
<link rel="import" href="../../../styles/shared-styles.html">
<link rel="import" href="../../core/gr-navigation/gr-navigation.html">
+<link rel="import" href="../../core/gr-reporting/gr-reporting.html">
<link rel="import" href="../../shared/gr-button/gr-button.html">
<link rel="import" href="../../shared/gr-count-string-formatter/gr-count-string-formatter.html">
<link rel="import" href="../../shared/gr-dropdown-list/gr-dropdown-list.html">
@@ -346,6 +347,7 @@
<gr-storage id="storage"></gr-storage>
<gr-diff-cursor id="cursor"></gr-diff-cursor>
<gr-comment-api id="commentAPI"></gr-comment-api>
+ <gr-reporting id="reporting"></gr-reporting>
</template>
<script src="gr-diff-view.js"></script>
</dom-module>
diff --git a/polygerrit-ui/app/elements/diff/gr-diff-view/gr-diff-view.js b/polygerrit-ui/app/elements/diff/gr-diff-view/gr-diff-view.js
index f4125a0..5df640e 100644
--- a/polygerrit-ui/app/elements/diff/gr-diff-view/gr-diff-view.js
+++ b/polygerrit-ui/app/elements/diff/gr-diff-view/gr-diff-view.js
@@ -618,7 +618,7 @@
promises.push(this._getChangeEdit(this._changeNum));
this._loading = true;
- Promise.all(promises).then(r => {
+ return Promise.all(promises).then(r => {
const edit = r[4];
if (edit) {
this.set('_change.revisions.' + edit.commit.commit, {
@@ -629,7 +629,9 @@
}
this._loading = false;
this.$.diff.comments = this._commentsForDiff;
- this.$.diff.reload();
+ return this.$.diff.reload();
+ }).then(() => {
+ this.$.reporting.diffViewDisplayed();
});
},
diff --git a/polygerrit-ui/app/elements/diff/gr-diff-view/gr-diff-view_test.html b/polygerrit-ui/app/elements/diff/gr-diff-view/gr-diff-view_test.html
index 46dbbdc..620286b 100644
--- a/polygerrit-ui/app/elements/diff/gr-diff-view/gr-diff-view_test.html
+++ b/polygerrit-ui/app/elements/diff/gr-diff-view/gr-diff-view_test.html
@@ -71,6 +71,23 @@
sandbox.restore();
});
+ test('params change triggers diffViewDisplayed()', () => {
+ sandbox.stub(element.$.reporting, 'diffViewDisplayed');
+ sandbox.stub(element.$.diff, 'reload').returns(Promise.resolve());
+ sandbox.spy(element, '_paramsChanged');
+ element.params = {
+ view: Gerrit.Nav.View.DIFF,
+ changeNum: '42',
+ patchNum: '2',
+ basePatchNum: '1',
+ path: '/COMMIT_MSG',
+ };
+
+ return element._paramsChanged.returnValues[0].then(() => {
+ assert.isTrue(element.$.reporting.diffViewDisplayed.calledOnce);
+ });
+ });
+
test('toggle left diff with a hotkey', () => {
const toggleLeftDiffStub = sandbox.stub(element.$.diff, 'toggleLeftDiff');
MockInteractions.pressAndReleaseKeyOn(element, 65, 'shift', 'a');
diff --git a/polygerrit-ui/app/styles/gr-menu-page-styles.html b/polygerrit-ui/app/styles/gr-menu-page-styles.html
index 6122a21..4adbeda 100644
--- a/polygerrit-ui/app/styles/gr-menu-page-styles.html
+++ b/polygerrit-ui/app/styles/gr-menu-page-styles.html
@@ -25,7 +25,12 @@
margin: 2em auto;
max-width: 50em;
}
- main.table {
+ .mainHeader {
+ margin-left: 14em;
+ padding: 1em 0 1em 2em;
+ }
+ main.table,
+ .mainHeader {
margin-top: 0;
margin-right: 0;
margin-left: 14em;
@@ -57,6 +62,10 @@
main.table {
margin: 0;
}
+ .mainHeader {
+ margin-left: 0;
+ padding: .5em 0 .5em 1em;
+ }
}
</style>
</template>