PolyGerrit: Implement support for /admin/project/<project>,branches
Change-Id: Ia1882c2831393f63c902965810fdaa72fc139391
This commit is contained in:
@@ -31,7 +31,7 @@ limitations under the License.
|
||||
items-per-page="[[_groupsPerPage]]"
|
||||
loading="[[_loading]]"
|
||||
offset="[[_offset]]"
|
||||
path="/admin/groups">
|
||||
path="[[_path]]">
|
||||
<table id="list">
|
||||
<tr class="headerRow">
|
||||
<th class="name topHeader">Group Name</th>
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
_path: {
|
||||
type: String,
|
||||
readOnly: true,
|
||||
value: '/admin/groups/',
|
||||
value: '/admin/groups',
|
||||
},
|
||||
_groups: Array,
|
||||
|
||||
@@ -77,7 +77,7 @@
|
||||
},
|
||||
|
||||
_computeGroupUrl(id) {
|
||||
return this.getUrl(this._path, id);
|
||||
return this.getUrl(this._path + '/', id);
|
||||
},
|
||||
|
||||
_getGroups(filter, groupsPerPage, offset) {
|
||||
|
||||
@@ -32,7 +32,7 @@ limitations under the License.
|
||||
items="[[_projects]]"
|
||||
loading="[[_loading]]"
|
||||
offset="[[_offset]]"
|
||||
path="/admin/projects">
|
||||
path="[[_path]]">
|
||||
<table id="list">
|
||||
<tr class="headerRow">
|
||||
<th class="name topHeader">Project Name</th>
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
_path: {
|
||||
type: String,
|
||||
readOnly: true,
|
||||
value: '/admin/projects/',
|
||||
value: '/admin/projects',
|
||||
},
|
||||
_projects: Array,
|
||||
|
||||
@@ -72,7 +72,7 @@
|
||||
},
|
||||
|
||||
_computeProjectUrl(name) {
|
||||
return this.getUrl(this._path, name);
|
||||
return this.getUrl(this._path + '/', name);
|
||||
},
|
||||
|
||||
_getProjects(filter, projectsPerPage, offset) {
|
||||
|
||||
@@ -28,6 +28,7 @@ limitations under the License.
|
||||
<link rel="import" href="../gr-admin-plugin-list/gr-admin-plugin-list.html">
|
||||
<link rel="import" href="../gr-admin-project-list/gr-admin-project-list.html">
|
||||
<link rel="import" href="../gr-admin-project/gr-admin-project.html">
|
||||
<link rel="import" href="../gr-project-branches/gr-project-branches.html">
|
||||
|
||||
<dom-module id="gr-admin-view">
|
||||
<template>
|
||||
@@ -93,6 +94,13 @@ limitations under the License.
|
||||
id="createProject"></gr-admin-create-project>
|
||||
</main>
|
||||
</template>
|
||||
<template is="dom-if" if="[[_showProjectBranches]]" restamp="true">
|
||||
<main class="table">
|
||||
<gr-project-branches
|
||||
params="[[params]]"
|
||||
class="table"></gr-project-branches>
|
||||
</main>
|
||||
</template>
|
||||
<template is="dom-if" if="[[params.placeholder]]" restamp="true">
|
||||
<gr-placeholder title="Admin" path="[[path]]"></gr-placeholder>
|
||||
</template>
|
||||
|
||||
@@ -64,6 +64,7 @@
|
||||
_showCreateProject: Boolean,
|
||||
_showProjectMain: Boolean,
|
||||
_showProjectList: Boolean,
|
||||
_showProjectBranches: Boolean,
|
||||
_showGroupList: Boolean,
|
||||
_showPluginList: Boolean,
|
||||
},
|
||||
@@ -106,8 +107,14 @@
|
||||
name: `${this._project}`,
|
||||
view: 'gr-admin-project',
|
||||
url: `/admin/projects/${this.encodeURL(this._project, true)}`,
|
||||
// TODO(beckysiegel): Branches
|
||||
children: [],
|
||||
children: [
|
||||
{
|
||||
name: 'Branches',
|
||||
view: 'gr-project-branches',
|
||||
url: `/admin/projects/${this.encodeURL(this._project, true)}` +
|
||||
',branches',
|
||||
},
|
||||
],
|
||||
};
|
||||
}
|
||||
filteredLinks.push(linkCopy);
|
||||
@@ -131,6 +138,8 @@
|
||||
this.set('_showProjectMain', params.adminView === 'gr-admin-project');
|
||||
this.set('_showProjectList',
|
||||
params.adminView === 'gr-admin-project-list');
|
||||
this.set('_showProjectBranches',
|
||||
params.adminView === 'gr-project-branches');
|
||||
this.set('_showGroupList', params.adminView === 'gr-admin-group-list');
|
||||
this.set('_showPluginList', params.adminView === 'gr-admin-plugin-list');
|
||||
if (params.project !== this._project) {
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
<!--
|
||||
Copyright (C) 2017 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
|
||||
<link rel="import" href="../../../behaviors/gr-list-view-behavior/gr-list-view-behavior.html">
|
||||
<link rel="import" href="../../../behaviors/gr-url-encoding-behavior.html">
|
||||
<link rel="import" href="../../../bower_components/iron-input/iron-input.html">
|
||||
<link rel="import" href="../../../bower_components/polymer/polymer.html">
|
||||
<link rel="import" href="../../shared/gr-list-view/gr-list-view.html">
|
||||
<link rel="import" href="../../shared/gr-rest-api-interface/gr-rest-api-interface.html">
|
||||
|
||||
<link rel="import" href="../../../styles/shared-styles.html">
|
||||
|
||||
|
||||
<dom-module id="gr-project-branches">
|
||||
<template>
|
||||
<style include="shared-styles"></style>
|
||||
<gr-list-view
|
||||
filter="[[_filter]]"
|
||||
items-per-page="[[_branchesPerPage]]"
|
||||
items="[[_branches]]"
|
||||
loading="[[_loading]]"
|
||||
offset="[[_offset]]"
|
||||
path="[[_getPath(_project)]]">
|
||||
<table id="list">
|
||||
<tr class="headerRow">
|
||||
<th class="name topHeader">Branch Name</th>
|
||||
<th class="description topHeader">Revision</th>
|
||||
<th class="repositoryBrowser topHeader">Repository Browser</th>
|
||||
</tr>
|
||||
<tr id="loading" class$="loadingMsg [[computeLoadingClass(_loading)]]">
|
||||
<td>Loading...</td>
|
||||
</tr>
|
||||
<template is="dom-repeat" items="[[_shownBranches]]"
|
||||
class$="[[computeLoadingClass(_loading)]]">
|
||||
<tr class="table">
|
||||
<td class="name">[[_stripRefsHeads(item.ref)]]</td>
|
||||
<td class="description">[[item.revision]]</td>
|
||||
<td class="repositoryBrowser">
|
||||
<template is="dom-repeat"
|
||||
items="[[_computeWeblink(item)]]" as="link">
|
||||
<a href$="[[link.url]]"
|
||||
class="webLink"
|
||||
rel="noopener"
|
||||
target="_blank">
|
||||
([[link.name]])
|
||||
</a>
|
||||
</template>
|
||||
</td>
|
||||
</tr>
|
||||
</template>
|
||||
</table>
|
||||
</gr-list-view>
|
||||
<gr-rest-api-interface id="restAPI"></gr-rest-api-interface>
|
||||
</template>
|
||||
<script src="gr-project-branches.js"></script>
|
||||
</dom-module>
|
||||
@@ -0,0 +1,96 @@
|
||||
// Copyright (C) 2017 The Android Open Source Project
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
Polymer({
|
||||
is: 'gr-project-branches',
|
||||
|
||||
properties: {
|
||||
/**
|
||||
* URL params passed from the router.
|
||||
*/
|
||||
params: {
|
||||
type: Object,
|
||||
observer: '_paramsChanged',
|
||||
},
|
||||
|
||||
/**
|
||||
* Offset of currently visible query results.
|
||||
*/
|
||||
_offset: Number,
|
||||
_project: Object,
|
||||
_branches: Array,
|
||||
/**
|
||||
* Because we request one more than the projectsPerPage, _shownProjects
|
||||
* maybe one less than _projects.
|
||||
* */
|
||||
_shownBranches: {
|
||||
type: Array,
|
||||
computed: 'computeShownItems(_branches)',
|
||||
},
|
||||
_branchesPerPage: {
|
||||
type: Number,
|
||||
value: 25,
|
||||
},
|
||||
_loading: {
|
||||
type: Boolean,
|
||||
value: true,
|
||||
},
|
||||
_filter: String,
|
||||
},
|
||||
|
||||
behaviors: [
|
||||
Gerrit.ListViewBehavior,
|
||||
Gerrit.URLEncodingBehavior,
|
||||
],
|
||||
|
||||
_paramsChanged(params) {
|
||||
this._loading = true;
|
||||
if (!params || !params.project) { return; }
|
||||
|
||||
this._project = params.project;
|
||||
|
||||
this._filter = this.getFilterValue(params);
|
||||
this._offset = this.getOffsetValue(params);
|
||||
|
||||
return this._getBranches(this._filter, this._project,
|
||||
this._branchesPerPage, this._offset);
|
||||
},
|
||||
|
||||
_getBranches(filter, project, projectsPerPage, offset) {
|
||||
this._projectsBranches = [];
|
||||
return this.$.restAPI.getProjectBranches(
|
||||
filter, project, projectsPerPage, offset) .then(branches => {
|
||||
if (!branches) { return; }
|
||||
this._branches = branches;
|
||||
this._loading = false;
|
||||
});
|
||||
},
|
||||
|
||||
_getPath(project) {
|
||||
return '/admin/projects/' + this.encodeURL(project, true) + ',branches';
|
||||
},
|
||||
|
||||
_computeWeblink(project) {
|
||||
if (!project.web_links) { return ''; }
|
||||
const webLinks = project.web_links;
|
||||
return webLinks.length ? webLinks : null;
|
||||
},
|
||||
|
||||
_stripRefsHeads(item) {
|
||||
return item.replace('refs/heads/', '');
|
||||
},
|
||||
});
|
||||
})();
|
||||
@@ -0,0 +1,150 @@
|
||||
<!DOCTYPE html>
|
||||
<!--
|
||||
Copyright (C) 2017 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
|
||||
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
|
||||
<title>gr-project-branches</title>
|
||||
|
||||
<script src="../../../bower_components/page/page.js"></script>
|
||||
<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
|
||||
<script src="../../../bower_components/web-component-tester/browser.js"></script>
|
||||
<link rel="import" href="../../../test/common-test-setup.html"/>
|
||||
<link rel="import" href="gr-project-branches.html">
|
||||
|
||||
<script>void(0);</script>
|
||||
|
||||
<test-fixture id="basic">
|
||||
<template>
|
||||
<gr-project-branches></gr-project-branches>
|
||||
</template>
|
||||
</test-fixture>
|
||||
|
||||
<script>
|
||||
let counter;
|
||||
const branchGenerator = () => {
|
||||
return {
|
||||
ref: `refs/heads/test${++counter}`,
|
||||
revision: '9c9d08a438e55e52f33b608415e6dddd9b18550d',
|
||||
web_links: [
|
||||
{
|
||||
name: 'diffusion',
|
||||
url: `https://git.example.org/branch/test;refs/heads/test${counter}`,
|
||||
},
|
||||
],
|
||||
};
|
||||
};
|
||||
|
||||
suite('gr-project-branches tests', () => {
|
||||
let element;
|
||||
let branches;
|
||||
let sandbox;
|
||||
|
||||
setup(() => {
|
||||
sandbox = sinon.sandbox.create();
|
||||
element = fixture('basic');
|
||||
counter = 0;
|
||||
});
|
||||
|
||||
teardown(() => {
|
||||
sandbox.restore();
|
||||
});
|
||||
|
||||
suite('list with project branches', () => {
|
||||
setup(done => {
|
||||
branches = _.times(26, branchGenerator);
|
||||
|
||||
stub('gr-rest-api-interface', {
|
||||
getProjectBranches(num, project, offset) {
|
||||
return Promise.resolve(branches);
|
||||
},
|
||||
});
|
||||
|
||||
const params = {
|
||||
project: 'test',
|
||||
};
|
||||
|
||||
element._paramsChanged(params).then(() => { flush(done); });
|
||||
});
|
||||
|
||||
test('test for test branch in the list', done => {
|
||||
flush(() => {
|
||||
assert.equal(element._branches[1].ref, 'refs/heads/test2');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
test('test for test web links in the branches list', done => {
|
||||
flush(() => {
|
||||
assert.equal(element._branches[1].web_links[0].url,
|
||||
'https://git.example.org/branch/test;refs/heads/test2');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
test('test for refs/heads/ being striped from ref', done => {
|
||||
flush(() => {
|
||||
assert.equal(element._stripRefsHeads(element._branches[1].ref),
|
||||
'test2');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
test('_shownBranches', () => {
|
||||
assert.equal(element._shownBranches.length, 25);
|
||||
});
|
||||
});
|
||||
|
||||
suite('list with less then 25 branches', () => {
|
||||
setup(done => {
|
||||
branches = _.times(25, branchGenerator);
|
||||
|
||||
stub('gr-rest-api-interface', {
|
||||
getProjectBranches(num, project, offset) {
|
||||
return Promise.resolve(branches);
|
||||
},
|
||||
});
|
||||
|
||||
const params = {
|
||||
project: 'test',
|
||||
};
|
||||
|
||||
element._paramsChanged(params).then(() => { flush(done); });
|
||||
});
|
||||
|
||||
test('_shownProjectsBranches', () => {
|
||||
assert.equal(element._shownBranches.length, 25);
|
||||
});
|
||||
});
|
||||
|
||||
suite('filter', () => {
|
||||
test('_paramsChanged', done => {
|
||||
sandbox.stub(element.$.restAPI, 'getProjectBranches', () => {
|
||||
return Promise.resolve(branches);
|
||||
});
|
||||
const params = {
|
||||
project: 'test',
|
||||
filter: 'test',
|
||||
offset: 25,
|
||||
};
|
||||
element._paramsChanged(params).then(() => {
|
||||
assert.isTrue(element.$.restAPI.getProjectBranches.lastCall
|
||||
.calledWithExactly('test', 'test', 25, 25));
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
</script>
|
||||
@@ -174,6 +174,38 @@
|
||||
});
|
||||
});
|
||||
|
||||
// Matches /admin/projects/<project/branches[,<offset>].
|
||||
page(/^\/admin\/projects\/(.+),branches(,(.+))?$/, loadUser, data => {
|
||||
app.params = {
|
||||
view: 'gr-admin-view',
|
||||
adminView: 'gr-project-branches',
|
||||
project: data.params[0],
|
||||
offset: data.params[2] || 0,
|
||||
filter: null,
|
||||
};
|
||||
});
|
||||
|
||||
page('/admin/projects/:project,branches/q/filter::filter,:offset',
|
||||
loadUser, data => {
|
||||
app.params = {
|
||||
view: 'gr-admin-view',
|
||||
adminView: 'gr-project-branches',
|
||||
project: data.params.project,
|
||||
offset: data.params.offset,
|
||||
filter: data.params.filter,
|
||||
};
|
||||
});
|
||||
|
||||
page('/admin/projects/:project,branches/q/filter::filter',
|
||||
loadUser, data => {
|
||||
app.params = {
|
||||
view: 'gr-admin-view',
|
||||
adminView: 'gr-project-branches',
|
||||
project: data.params.project,
|
||||
filter: data.params.filter || null,
|
||||
};
|
||||
});
|
||||
|
||||
// Matches /admin/projects[,<offset>][/].
|
||||
page(/^\/admin\/projects(,(\d+))?(\/)?$/, loadUser, data => {
|
||||
app.params = {
|
||||
|
||||
@@ -55,10 +55,10 @@
|
||||
}, REQUEST_DEBOUNCE_INTERVAL_MS);
|
||||
},
|
||||
|
||||
_computeNavLink(offset, direction, projectsPerPage, filter) {
|
||||
_computeNavLink(offset, direction, itemsPerPage, filter) {
|
||||
// Offset could be a string when passed from the router.
|
||||
offset = +(offset || 0);
|
||||
const newOffset = Math.max(0, offset + (projectsPerPage * direction));
|
||||
const newOffset = Math.max(0, offset + (itemsPerPage * direction));
|
||||
let href = this.getBaseUrl() + this.path;
|
||||
if (filter) {
|
||||
href += '/q/filter:' + filter;
|
||||
@@ -73,12 +73,12 @@
|
||||
return offset === 0;
|
||||
},
|
||||
|
||||
_hideNextArrow(loading, projects) {
|
||||
_hideNextArrow(loading, items) {
|
||||
let lastPage = false;
|
||||
if (projects.length < this.itemsPerPage + 1) {
|
||||
if (items.length < this.itemsPerPage + 1) {
|
||||
lastPage = true;
|
||||
}
|
||||
return loading || lastPage || !projects || !projects.length;
|
||||
return loading || lastPage || !items || !items.length;
|
||||
},
|
||||
});
|
||||
})();
|
||||
|
||||
@@ -523,6 +523,16 @@
|
||||
);
|
||||
},
|
||||
|
||||
getProjectBranches(filter, project, projectsBranchesPerPage, opt_offset) {
|
||||
const offset = opt_offset || 0;
|
||||
filter = filter ? '&m=' + filter : '';
|
||||
|
||||
return this._fetchSharedCacheURL(
|
||||
`/projects/${project}/branches?n=${projectsBranchesPerPage + 1}&s=` +
|
||||
`${offset}${filter}`
|
||||
);
|
||||
},
|
||||
|
||||
getPlugins() {
|
||||
return this._fetchSharedCacheURL('/plugins/?all');
|
||||
},
|
||||
|
||||
@@ -36,6 +36,7 @@ limitations under the License.
|
||||
'admin/gr-admin-project/gr-admin-project_test.html',
|
||||
'admin/gr-admin-project-list/gr-admin-project-list_test.html',
|
||||
'admin/gr-admin-view/gr-admin-view_test.html',
|
||||
'admin/gr-project-branches/gr-project-branches_test.html',
|
||||
'change-list/gr-change-list-item/gr-change-list-item_test.html',
|
||||
'change-list/gr-change-list-view/gr-change-list-view_test.html',
|
||||
'change-list/gr-change-list/gr-change-list_test.html',
|
||||
|
||||
Reference in New Issue
Block a user