Add top level admin dropdown to gr-main-header

In the event there are plugin generated links, ones with out beginning
'/' are presumed to be external and open in a new tab. Others are
treated as internal links.

Change-Id: Ie8ee347b839f39d25af78dc30174f2a95c8cfd19
This commit is contained in:
Becky Siegel
2018-04-19 09:49:29 +02:00
parent cad4bf8108
commit 6133a7470b
6 changed files with 59 additions and 17 deletions

View File

@@ -91,13 +91,16 @@ limitations under the License.
let links = ADMIN_LINKS.slice(0);
let expandedSection;
const isExernalLink = link => link.url[0] !== '/';
// Append top-level links that are defined by plugins.
links.push(...getAdminMenuLinks().map(link => ({
url: link.url,
name: link.text,
noBaseUrl: link.url[0] === '/',
noBaseUrl: !isExernalLink(link),
view: null,
viewableToAll: true,
target: isExernalLink(link) ? '_blank' : null,
})));
links = links.filter(filterFn);

View File

@@ -93,9 +93,17 @@ limitations under the License.
if (expected.pluginGeneratedLinks) {
for (const link of expected.pluginGeneratedLinks) {
assert.isTrue(!!res.links.find(l => {
const linkMatch = res.links.find(l => {
return (l.url === link.url && l.name === link.text);
}));
});
assert.isTrue(!!linkMatch);
// External links should open in new tab.
if (link.url[0] !== '/') {
assert.equal(linkMatch.target, '_blank');
} else {
assert.isNotOk(linkMatch.target);
}
}
}

View File

@@ -162,6 +162,7 @@ limitations under the License.
noBaseUrl: true,
view: null,
viewableToAll: true,
target: null,
});
assert.deepEqual(element._filteredLinks[2], {
url: 'http://external/link/url',
@@ -169,6 +170,7 @@ limitations under the License.
noBaseUrl: false,
view: null,
viewableToAll: true,
target: '_blank',
});
});
});

View File

@@ -18,8 +18,10 @@ limitations under the License.
<link rel="import" href="../../../behaviors/docs-url-behavior/docs-url-behavior.html">
<link rel="import" href="../../../behaviors/base-url-behavior/base-url-behavior.html">
<link rel="import" href="../../../behaviors/gr-admin-nav-behavior/gr-admin-nav-behavior.html">
<link rel="import" href="../../plugins/gr-endpoint-decorator/gr-endpoint-decorator.html">
<link rel="import" href="../../shared/gr-dropdown/gr-dropdown.html">
<link rel="import" href="../../shared/gr-js-api-interface/gr-js-api-interface.html">
<link rel="import" href="../../shared/gr-rest-api-interface/gr-rest-api-interface.html">
<link rel="import" href="../gr-account-dropdown/gr-account-dropdown.html">
<link rel="import" href="../gr-smart-search/gr-smart-search.html">
@@ -170,12 +172,6 @@ limitations under the License.
</gr-dropdown>
</li>
</template>
<li>
<a
class="browse linksTitle"
href$="[[_computeRelativeURL('/admin/repos')]]">
Browse</a>
</li>
</ul>
<div class="rightItems">
<gr-smart-search
@@ -190,6 +186,7 @@ limitations under the License.
</div>
</div>
</nav>
<gr-js-api-interface id="jsAPI"></gr-js-api-interface>
<gr-rest-api-interface id="restAPI"></gr-rest-api-interface>
</template>
<script src="gr-main-header.js"></script>

View File

@@ -93,7 +93,8 @@
},
_links: {
type: Array,
computed: '_computeLinks(_defaultLinks, _userLinks, _docBaseUrl)',
computed: '_computeLinks(_defaultLinks, _userLinks, _adminLinks, ' +
'_docBaseUrl)',
},
_loginURL: {
type: String,
@@ -106,6 +107,7 @@
},
behaviors: [
Gerrit.AdminNavBehavior,
Gerrit.BaseUrlBehavior,
Gerrit.DocsUrlBehavior,
],
@@ -149,7 +151,7 @@
return '//' + window.location.host + this.getBaseUrl() + path;
},
_computeLinks(defaultLinks, userLinks, docBaseUrl) {
_computeLinks(defaultLinks, userLinks, adminLinks, docBaseUrl) {
const links = defaultLinks.slice();
if (userLinks && userLinks.length > 0) {
links.push({
@@ -165,6 +167,10 @@
class: 'hideOnMobile',
});
}
links.push({
title: 'Browse',
links: adminLinks,
});
return links;
},
@@ -186,10 +192,23 @@
},
_loadAccount() {
return this.$.restAPI.getAccount().then(account => {
const promises = [
this.$.restAPI.getAccount(),
Gerrit.awaitPluginsLoaded(),
];
return Promise.all(promises).then(result => {
const account = result[0];
this._account = account;
this.$.accountContainer.classList.toggle('loggedIn', account != null);
this.$.accountContainer.classList.toggle('loggedOut', account == null);
return this.getAdminLinks(account,
this.$.restAPI.getAccountCapabilities.bind(this.$.restAPI),
this.$.jsAPI.getAdminMenuLinks.bind(this.$.jsAPI))
.then(res => {
this._adminLinks = res.links;
});
});
},

View File

@@ -87,15 +87,28 @@ limitations under the License.
name: 'Facebook',
url: 'https://facebook.com',
}];
const adminLinks = [{
name: 'Repos',
url: '/repos',
}];
// When no admin links are passed, it should use the default.
assert.deepEqual(element._computeLinks(defaultLinks, []), defaultLinks);
assert.deepEqual(
element._computeLinks(defaultLinks, userLinks),
assert.deepEqual(element._computeLinks(defaultLinks, [], adminLinks),
defaultLinks.concat({
title: 'Your',
links: userLinks,
title: 'Browse',
links: adminLinks,
}));
assert.deepEqual(
element._computeLinks(defaultLinks, userLinks, adminLinks),
defaultLinks.concat([
{
title: 'Your',
links: userLinks,
},
{
title: 'Browse',
links: adminLinks,
}]));
});
test('documentation links', () => {