Merge "Add project specific nav to sidebar"
This commit is contained in:
commit
046d4df941
polygerrit-ui/app/elements
admin/gr-admin-view
shared/gr-page-nav
@ -17,6 +17,7 @@ limitations under the License.
|
||||
<link rel="import" href="../../../bower_components/polymer/polymer.html">
|
||||
|
||||
<link rel="import" href="../../../behaviors/base-url-behavior/base-url-behavior.html">
|
||||
<link rel="import" href="../../../behaviors/gr-url-encoding-behavior.html">
|
||||
<link rel="import" href="../../../styles/gr-menu-page-styles.html">
|
||||
<link rel="import" href="../../../styles/shared-styles.html">
|
||||
<link rel="import" href="../../shared/gr-page-nav/gr-page-nav.html">
|
||||
@ -34,17 +35,32 @@ limitations under the License.
|
||||
<style include="gr-menu-page-styles"></style>
|
||||
<gr-page-nav class$="[[_computeLoadingClass(_loading)]]">
|
||||
<ul class="sectionContent">
|
||||
<template is="dom-repeat" items="[[_filteredLinks]]">
|
||||
<template id="adminNav" is="dom-repeat" items="[[_filteredLinks]]">
|
||||
<li class$="sectionTitle [[_computeSelectedClass(item.view, params)]]">
|
||||
<a class="title" href="[[_computeLinkURL(item)]]"
|
||||
rel$="[[_computeLinkRel(item)]]">[[item.name]]</a>
|
||||
</li>
|
||||
<template is="dom-repeat" items="[[item.children]]">
|
||||
<li class$="[[_computeSelectedClass(item.view, params)]]">
|
||||
<a href="[[_computeLinkURL(item)]]"
|
||||
rel$="[[_computeLinkRel(item)]]">[[item.name]]</a>
|
||||
<template is="dom-repeat" items="[[item.children]]" as="child">
|
||||
<li class$="[[_computeSelectedClass(child.view, params)]]">
|
||||
<a href$="[[_computeLinkURL(child)]]"
|
||||
rel="noopener">[[child.name]]</a>
|
||||
</li>
|
||||
</template>
|
||||
<template is="dom-if" if="[[item.subsection]]">
|
||||
<!--If a section has a subsection, render that.-->
|
||||
<li class$="[[_computeSelectedClass(item.subsection.view, params)]]">
|
||||
<a class="title" href$="[[_computeLinkURL(item.subsection)]]"
|
||||
rel$="[[_computeLinkRel(item.subsection)]]">
|
||||
[[item.subsection.name]]</a>
|
||||
</li>
|
||||
<!--Loop through the links in the sub-section.-->
|
||||
<template is="dom-repeat"
|
||||
items="[[item.subsection.children]]" as="child">
|
||||
<li class$="subsectionItem [[_computeSelectedClass(child.view, params)]]">
|
||||
<a href$="[[_computeLinkURL(child)]]">[[child.name]]</a>
|
||||
</li>
|
||||
</template>
|
||||
</template>
|
||||
</template>
|
||||
</ul>
|
||||
</gr-page-nav>
|
||||
|
@ -55,6 +55,7 @@
|
||||
path: String,
|
||||
adminView: String,
|
||||
|
||||
_project: String,
|
||||
_filteredLinks: Array,
|
||||
_showDownload: {
|
||||
type: Boolean,
|
||||
@ -69,6 +70,7 @@
|
||||
|
||||
behaviors: [
|
||||
Gerrit.BaseUrlBehavior,
|
||||
Gerrit.URLEncodingBehavior,
|
||||
],
|
||||
|
||||
observers: [
|
||||
@ -94,10 +96,23 @@
|
||||
|
||||
_filterLinks(filterFn) {
|
||||
const links = ADMIN_LINKS.filter(filterFn);
|
||||
const filteredLinks = [];
|
||||
for (const link of links) {
|
||||
link.children = link.children ? link.children.filter(filterFn) : [];
|
||||
const linkCopy = Object.assign({}, link);
|
||||
linkCopy.children = linkCopy.children ?
|
||||
linkCopy.children.filter(filterFn) : [];
|
||||
if (linkCopy.name === 'Projects' && this._project) {
|
||||
linkCopy.subsection = {
|
||||
name: `${this._project}`,
|
||||
view: 'gr-admin-project',
|
||||
url: `/admin/projects/${this.encodeURL(this._project, true)}`,
|
||||
// TODO(beckysiegel): Branches
|
||||
children: [],
|
||||
};
|
||||
}
|
||||
filteredLinks.push(linkCopy);
|
||||
}
|
||||
return links;
|
||||
return filteredLinks;
|
||||
},
|
||||
|
||||
_loadAccountCapabilities() {
|
||||
@ -110,29 +125,6 @@
|
||||
});
|
||||
},
|
||||
|
||||
_computeSideLinks(unformattedLinks) {
|
||||
const topLevelLinks = unformattedLinks.filter(link => {
|
||||
return link.topLevel;
|
||||
});
|
||||
|
||||
const nestedLinks = unformattedLinks.filter(link => {
|
||||
return !link.topLevel;
|
||||
});
|
||||
|
||||
return topLevelLinks.map(item => {
|
||||
const section = {
|
||||
name: item.name,
|
||||
url: item.url,
|
||||
view: item.view,
|
||||
};
|
||||
const newLinks = nestedLinks.filter(group => {
|
||||
return group.section === section.name;
|
||||
});
|
||||
section.links = newLinks;
|
||||
return section;
|
||||
});
|
||||
},
|
||||
|
||||
_paramsChanged(params) {
|
||||
this.set('_showCreateProject',
|
||||
params.adminView === 'gr-admin-create-project');
|
||||
@ -141,6 +133,11 @@
|
||||
params.adminView === 'gr-admin-project-list');
|
||||
this.set('_showGroupList', params.adminView === 'gr-admin-group-list');
|
||||
this.set('_showPluginList', params.adminView === 'gr-admin-plugin-list');
|
||||
if (params.project !== this._project) {
|
||||
this._project = params.project || '';
|
||||
// Reloads the admin menu.
|
||||
this.reload();
|
||||
}
|
||||
},
|
||||
|
||||
// TODO (beckysiegel): Update these functions after router abstraction is
|
||||
@ -156,19 +153,13 @@
|
||||
},
|
||||
|
||||
_computeLinkURL(link) {
|
||||
if (typeof link.url === 'undefined') {
|
||||
return '';
|
||||
}
|
||||
if (!link || typeof link.url === 'undefined') { return ''; }
|
||||
if (link.target) {
|
||||
return link.url;
|
||||
}
|
||||
return this._computeRelativeURL(link.url);
|
||||
},
|
||||
|
||||
_computeLinkRel(link) {
|
||||
return link.target ? 'noopener' : null;
|
||||
},
|
||||
|
||||
_computeSelectedClass(itemView, params) {
|
||||
return itemView === params.adminView ? 'selected' : '';
|
||||
},
|
||||
|
@ -39,6 +39,11 @@ limitations under the License.
|
||||
setup(() => {
|
||||
sandbox = sinon.sandbox.create();
|
||||
element = fixture('basic');
|
||||
stub('gr-rest-api-interface', {
|
||||
getProjectConfig() {
|
||||
return Promise.resolve({});
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
teardown(() => {
|
||||
@ -99,6 +104,7 @@ limitations under the License.
|
||||
|
||||
// Projects
|
||||
assert.equal(element._filteredLinks[0].children.length, 1);
|
||||
assert.isNotOk(element._filteredLinks[0].subsection);
|
||||
|
||||
// Groups
|
||||
assert.equal(element._filteredLinks[1].children.length, 1);
|
||||
@ -118,6 +124,7 @@ limitations under the License.
|
||||
|
||||
// Projects
|
||||
assert.equal(element._filteredLinks[0].children.length, 0);
|
||||
assert.isNotOk(element._filteredLinks[0].subsection);
|
||||
|
||||
// Groups
|
||||
assert.equal(element._filteredLinks[1].children.length, 0);
|
||||
@ -131,8 +138,53 @@ limitations under the License.
|
||||
|
||||
// Projects
|
||||
assert.equal(element._filteredLinks[0].children.length, 0);
|
||||
assert.isNotOk(element._filteredLinks[0].subsection);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
test('Project shows up in nav', done => {
|
||||
element._project = 'Test Project';
|
||||
sandbox.stub(element.$.restAPI, 'getAccountCapabilities', () => {
|
||||
return Promise.resolve({
|
||||
createGroup: true,
|
||||
createProject: true,
|
||||
viewPlugins: true,
|
||||
});
|
||||
});
|
||||
element._loadAccountCapabilities().then(() => {
|
||||
assert.equal(element._filteredLinks.length, 3);
|
||||
|
||||
// Projects
|
||||
assert.equal(element._filteredLinks[0].children.length, 1);
|
||||
assert.equal(element._filteredLinks[0].subsection.name, 'Test Project');
|
||||
|
||||
// Groups
|
||||
assert.equal(element._filteredLinks[1].children.length, 1);
|
||||
|
||||
// Plugins
|
||||
assert.equal(element._filteredLinks[2].children.length, 0);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
test('Nav is reloaded when project changes', () => {
|
||||
sandbox.stub(element.$.restAPI, 'getAccountCapabilities', () => {
|
||||
return Promise.resolve({
|
||||
createGroup: true,
|
||||
createProject: true,
|
||||
viewPlugins: true,
|
||||
});
|
||||
});
|
||||
sandbox.stub(element.$.restAPI, 'getAccount', () => {
|
||||
return Promise.resolve({_id: 1});
|
||||
});
|
||||
sandbox.stub(element, 'reload');
|
||||
element.params = {project: 'Test Project', adminView: 'gr-admin-project'};
|
||||
assert.equal(element.reload.callCount, 1);
|
||||
element.params = {project: 'Test Project 2',
|
||||
adminView: 'gr-admin-project'};
|
||||
assert.equal(element.reload.callCount, 2);
|
||||
});
|
||||
});
|
||||
</script>
|
@ -40,6 +40,9 @@ limitations under the License.
|
||||
border-top: 1px solid transparent;
|
||||
padding: 0 2em;
|
||||
}
|
||||
#nav ::content li a {
|
||||
word-break: break-all;
|
||||
}
|
||||
#nav ::content .subsectionItem {
|
||||
padding-left: 3em;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user