Rename projects admin interface to repo

This also includes backwards compatibility with the old /projects/ url.

This only renames it for the admin interface. It does not rename it for
changes or anything else.

Bug: Issue 7754
Change-Id: Ia31d3f26871556729fb3c5b5b28ceca12da1ec7c
This commit is contained in:
Paladox none 2017-11-16 18:54:02 +00:00
parent aeeba877f7
commit 2bd5c217d0
49 changed files with 758 additions and 727 deletions

View File

@ -224,15 +224,15 @@ Note: TODO
Note: TODO Note: TODO
[plugin-project] [plugin-repo]
=== project === repo
`plugin.project()` `plugin.repo()`
.Params: .Params:
- none - none
.Returns: .Returns:
- Instance of link:pg-plugin-project-api.html[GrProjectApi]. - Instance of link:pg-plugin-repo-api.html[GrRepoApi].
=== put === put
`plugin.put(url, payload, opt_callback)` `plugin.put(url, payload, opt_callback)`

View File

@ -1,36 +0,0 @@
= Gerrit Code Review - Project admin customization API
This API is provided by link:pg-plugin-dev.html#plugin-project[plugin.project()]
and provides customization to admin page.
== createCommand
`projectApi.createCommand(title, checkVisibleCallback)`
Create a project command in the admin panel.
.Params
- *title* String title.
- *checkVisibleCallback* function to configure command visibility.
.Returns
- GrProjectApi for chaining.
`checkVisibleCallback(projectName, projectConfig)`
.Params
- *projectName* String project name.
- *projectConfig* Object REST API response for project config.
.Returns
- `false` to hide the command for the specific project.
== onTap
`projectApi.onTap(tapCalback)`
Add a command tap callback.
.Params
- *tapCallback* function that's excuted on command tap.
.Returns
- Nothing

View File

@ -0,0 +1,36 @@
= Gerrit Code Review - Repo admin customization API
This API is provided by link:pg-plugin-dev.html#plugin-repo[plugin.repo()]
and provides customization to admin page.
== createCommand
`repoApi.createCommand(title, checkVisibleCallback)`
Create a repo command in the admin panel.
.Params
- *title* String title.
- *checkVisibleCallback* function to configure command visibility.
.Returns
- GrRepoApi for chaining.
`checkVisibleCallback(repoName, repoConfig)`
.Params
- *repoName* String project name.
- *repoConfig* Object REST API response for repo config.
.Returns
- `false` to hide the command for the specific project.
== onTap
`repoApi.onTap(tapCalback)`
Add a command tap callback.
.Params
- *tapCallback* function that's excuted on command tap.
.Returns
- Nothing

View File

@ -29,11 +29,11 @@ limitations under the License.
<link rel="import" href="../gr-group-audit-log/gr-group-audit-log.html"> <link rel="import" href="../gr-group-audit-log/gr-group-audit-log.html">
<link rel="import" href="../gr-group-members/gr-group-members.html"> <link rel="import" href="../gr-group-members/gr-group-members.html">
<link rel="import" href="../gr-plugin-list/gr-plugin-list.html"> <link rel="import" href="../gr-plugin-list/gr-plugin-list.html">
<link rel="import" href="../gr-project/gr-project.html"> <link rel="import" href="../gr-repo/gr-repo.html">
<link rel="import" href="../gr-project-access/gr-project-access.html"> <link rel="import" href="../gr-repo-access/gr-repo-access.html">
<link rel="import" href="../gr-project-commands/gr-project-commands.html"> <link rel="import" href="../gr-repo-commands/gr-repo-commands.html">
<link rel="import" href="../gr-project-detail-list/gr-project-detail-list.html"> <link rel="import" href="../gr-repo-detail-list/gr-repo-detail-list.html">
<link rel="import" href="../gr-project-list/gr-project-list.html"> <link rel="import" href="../gr-repo-list/gr-repo-list.html">
<dom-module id="gr-admin-view"> <dom-module id="gr-admin-view">
<template> <template>
@ -71,14 +71,14 @@ limitations under the License.
</template> </template>
</ul> </ul>
</gr-page-nav> </gr-page-nav>
<template is="dom-if" if="[[_showProjectList]]" restamp="true"> <template is="dom-if" if="[[_showRepoList]]" restamp="true">
<main class="table"> <main class="table">
<gr-project-list class="table" params="[[params]]"></gr-project-list> <gr-repo-list class="table" params="[[params]]"></gr-repo-list>
</main> </main>
</template> </template>
<template is="dom-if" if="[[_showProjectMain]]" restamp="true"> <template is="dom-if" if="[[_showRepoMain]]" restamp="true">
<main> <main>
<gr-project project="[[params.project]]"></gr-project> <gr-repo repo="[[params.repo]]"></gr-repo>
</main> </main>
</template> </template>
<template is="dom-if" if="[[_showGroup]]" restamp="true"> <template is="dom-if" if="[[_showGroup]]" restamp="true">
@ -105,11 +105,11 @@ limitations under the License.
<gr-plugin-list class="table" params="[[params]]"></gr-plugin-list> <gr-plugin-list class="table" params="[[params]]"></gr-plugin-list>
</main> </main>
</template> </template>
<template is="dom-if" if="[[_showProjectDetailList]]" restamp="true"> <template is="dom-if" if="[[_showRepoDetailList]]" restamp="true">
<main class="table"> <main class="table">
<gr-project-detail-list <gr-repo-detail-list
params="[[params]]" params="[[params]]"
class="table"></gr-project-detail-list> class="table"></gr-repo-detail-list>
</main> </main>
</template> </template>
<template is="dom-if" if="[[_showGroupAuditLog]]" restamp="true"> <template is="dom-if" if="[[_showGroupAuditLog]]" restamp="true">
@ -119,17 +119,17 @@ limitations under the License.
class="table"></gr-group-audit-log> class="table"></gr-group-audit-log>
</main> </main>
</template> </template>
<template is="dom-if" if="[[_showProjectCommands]]" restamp="true"> <template is="dom-if" if="[[_showRepoCommands]]" restamp="true">
<main> <main>
<gr-project-commands <gr-repo-commands
project="[[params.project]]"></gr-project-commands> repo="[[params.repo]]"></gr-repo-commands>
</main> </main>
</template> </template>
<template is="dom-if" if="[[_showProjectAccess]]" restamp="true"> <template is="dom-if" if="[[_showRepoAccess]]" restamp="true">
<main class="table"> <main class="table">
<gr-project-access <gr-repo-access
path="[[path]]" path="[[path]]"
project="[[params.project]]"></gr-project-access> repo="[[params.repo]]"></gr-repo-access>
</main> </main>
</template> </template>
<gr-rest-api-interface id="restAPI"></gr-rest-api-interface> <gr-rest-api-interface id="restAPI"></gr-rest-api-interface>

View File

@ -17,10 +17,10 @@
// Note: noBaseUrl: true is set on entries where the URL is not yet supported // Note: noBaseUrl: true is set on entries where the URL is not yet supported
// by router abstraction. // by router abstraction.
const ADMIN_LINKS = [{ const ADMIN_LINKS = [{
name: 'Projects', name: 'Repositories',
noBaseUrl: true, noBaseUrl: true,
url: '/admin/projects', url: '/admin/repos',
view: 'gr-project-list', view: 'gr-repo-list',
viewableToAll: true, viewableToAll: true,
children: [], children: [],
}, { }, {
@ -50,7 +50,7 @@
path: String, path: String,
adminView: String, adminView: String,
_projectName: String, _repoName: String,
_groupId: { _groupId: {
type: Number, type: Number,
observer: '_computeGroupName', observer: '_computeGroupName',
@ -73,12 +73,12 @@
_showGroupAuditLog: Boolean, _showGroupAuditLog: Boolean,
_showGroupList: Boolean, _showGroupList: Boolean,
_showGroupMembers: Boolean, _showGroupMembers: Boolean,
_showProjectCommands: Boolean, _showRepoAccess: Boolean,
_showProjectMain: Boolean, _showRepoCommands: Boolean,
_showProjectList: Boolean, _showRepoDetailList: Boolean,
_showProjectDetailList: Boolean, _showRepoMain: Boolean,
_showRepoList: Boolean,
_showPluginList: Boolean, _showPluginList: Boolean,
_showProjectAccess: Boolean,
}, },
behaviors: [ behaviors: [
@ -114,43 +114,43 @@
const linkCopy = Object.assign({}, link); const linkCopy = Object.assign({}, link);
linkCopy.children = linkCopy.children ? linkCopy.children = linkCopy.children ?
linkCopy.children.filter(filterFn) : []; linkCopy.children.filter(filterFn) : [];
if (linkCopy.name === 'Projects' && this._projectName) { if (linkCopy.name === 'Repositories' && this._repoName) {
linkCopy.subsection = { linkCopy.subsection = {
name: this._projectName, name: this._repoName,
view: 'gr-project', view: 'gr-repo',
noBaseUrl: true, noBaseUrl: true,
url: `/admin/projects/${this.encodeURL(this._projectName, true)}`, url: `/admin/repos/${this.encodeURL(this._repoName, true)}`,
children: [{ children: [{
name: 'Access', name: 'Access',
detailType: 'access', detailType: 'access',
view: 'gr-project-access', view: 'gr-repo-access',
noBaseUrl: true, noBaseUrl: true,
url: `/admin/projects/` + url: `/admin/repos/` +
`${this.encodeURL(this._projectName, true)},access`, `${this.encodeURL(this._repoName, true)},access`,
}, },
{ {
name: 'Commands', name: 'Commands',
detailType: 'commands', detailType: 'commands',
view: 'gr-project-commands', view: 'gr-repo-commands',
noBaseUrl: true, noBaseUrl: true,
url: `/admin/projects/` + url: `/admin/repos/` +
`${this.encodeURL(this._projectName, true)},commands`, `${this.encodeURL(this._repoName, true)},commands`,
}, },
{ {
name: 'Branches', name: 'Branches',
detailType: 'branches', detailType: 'branches',
view: 'gr-project-detail-list', view: 'gr-repo-detail-list',
noBaseUrl: true, noBaseUrl: true,
url: `/admin/projects/` + url: `/admin/repos/` +
`${this.encodeURL(this._projectName, true)},branches`, `${this.encodeURL(this._repoName, true)},branches`,
}, },
{ {
name: 'Tags', name: 'Tags',
detailType: 'tags', detailType: 'tags',
view: 'gr-project-detail-list', view: 'gr-repo-detail-list',
noBaseUrl: true, noBaseUrl: true,
url: `/admin/projects/` + url: `/admin/repos/` +
`${this.encodeURL(this._projectName, true)},tags`, `${this.encodeURL(this._repoName, true)},tags`,
}], }],
}; };
} }
@ -207,21 +207,21 @@
this.set('_showGroupList', isAdminView && this.set('_showGroupList', isAdminView &&
params.adminView === 'gr-admin-group-list'); params.adminView === 'gr-admin-group-list');
this.set('_showProjectCommands', isAdminView && this.set('_showRepoAccess', isAdminView &&
params.adminView === 'gr-project-commands'); params.adminView === 'gr-repo-access');
this.set('_showProjectMain', isAdminView && this.set('_showRepoCommands', isAdminView &&
params.adminView === 'gr-project'); params.adminView === 'gr-repo-commands');
this.set('_showProjectList', isAdminView && this.set('_showRepoDetailList', isAdminView &&
params.adminView === 'gr-project-list'); params.adminView === 'gr-repo-detail-list');
this.set('_showProjectDetailList', isAdminView && this.set('_showRepoMain', isAdminView &&
params.adminView === 'gr-project-detail-list'); params.adminView === 'gr-repo');
this.set('_showRepoList', isAdminView &&
params.adminView === 'gr-repo-list');
this.set('_showPluginList', isAdminView && this.set('_showPluginList', isAdminView &&
params.adminView === 'gr-plugin-list'); params.adminView === 'gr-plugin-list');
this.set('_showProjectAccess', isAdminView &&
params.adminView === 'gr-project-access');
if (params.project !== this._projectName) { if (params.repo !== this._repoName) {
this._projectName = params.project || ''; this._repoName = params.repo || '';
// Reloads the admin menu. // Reloads the admin menu.
this.reload(); this.reload();
} }

View File

@ -74,22 +74,22 @@ limitations under the License.
test('current page gets selected and is displayed', () => { test('current page gets selected and is displayed', () => {
element._filteredLinks = [{ element._filteredLinks = [{
name: 'Projects', name: 'Repositories',
url: '/admin/projects', url: '/admin/repos',
view: 'gr-project-list', view: 'gr-repo-list',
children: [], children: [],
}]; }];
element.params = { element.params = {
view: 'admin', view: 'admin',
adminView: 'gr-project-list', adminView: 'gr-repo-list',
}; };
flushAsynchronousOperations(); flushAsynchronousOperations();
assert.equal(Polymer.dom(element.root).querySelectorAll( assert.equal(Polymer.dom(element.root).querySelectorAll(
'.selected').length, 1); '.selected').length, 1);
assert.ok(element.$$('gr-project-list')); assert.ok(element.$$('gr-repo-list'));
assert.isNotOk(element.$$('gr-admin-create-project')); assert.isNotOk(element.$$('gr-admin-create-repo'));
}); });
test('_filteredLinks admin', done => { test('_filteredLinks admin', done => {
@ -103,7 +103,7 @@ limitations under the License.
element._loadAccountCapabilities().then(() => { element._loadAccountCapabilities().then(() => {
assert.equal(element._filteredLinks.length, 3); assert.equal(element._filteredLinks.length, 3);
// Projects // Repos
assert.equal(element._filteredLinks[0].children.length, 0); assert.equal(element._filteredLinks[0].children.length, 0);
assert.isNotOk(element._filteredLinks[0].subsection); assert.isNotOk(element._filteredLinks[0].subsection);
@ -123,7 +123,7 @@ limitations under the License.
element._loadAccountCapabilities().then(() => { element._loadAccountCapabilities().then(() => {
assert.equal(element._filteredLinks.length, 2); assert.equal(element._filteredLinks.length, 2);
// Projects // Repos
assert.equal(element._filteredLinks[0].children.length, 0); assert.equal(element._filteredLinks[0].children.length, 0);
assert.isNotOk(element._filteredLinks[0].subsection); assert.isNotOk(element._filteredLinks[0].subsection);
@ -137,15 +137,15 @@ limitations under the License.
element.reload().then(() => { element.reload().then(() => {
assert.equal(element._filteredLinks.length, 1); assert.equal(element._filteredLinks.length, 1);
// Projects // Repos
assert.equal(element._filteredLinks[0].children.length, 0); assert.equal(element._filteredLinks[0].children.length, 0);
assert.isNotOk(element._filteredLinks[0].subsection); assert.isNotOk(element._filteredLinks[0].subsection);
done(); done();
}); });
}); });
test('Project shows up in nav', done => { test('Repo shows up in nav', done => {
element._projectName = 'Test Project'; element._repoName = 'Test Repo';
sandbox.stub(element.$.restAPI, 'getAccountCapabilities', () => { sandbox.stub(element.$.restAPI, 'getAccountCapabilities', () => {
return Promise.resolve({ return Promise.resolve({
createGroup: true, createGroup: true,
@ -156,9 +156,9 @@ limitations under the License.
element._loadAccountCapabilities().then(() => { element._loadAccountCapabilities().then(() => {
assert.equal(element._filteredLinks.length, 3); assert.equal(element._filteredLinks.length, 3);
// Projects // Repos
assert.equal(element._filteredLinks[0].children.length, 0); assert.equal(element._filteredLinks[0].children.length, 0);
assert.equal(element._filteredLinks[0].subsection.name, 'Test Project'); assert.equal(element._filteredLinks[0].subsection.name, 'Test Repo');
// Groups // Groups
assert.equal(element._filteredLinks[1].children.length, 0); assert.equal(element._filteredLinks[1].children.length, 0);
@ -169,7 +169,7 @@ limitations under the License.
}); });
}); });
test('Nav is reloaded when project changes', () => { test('Nav is reloaded when repo changes', () => {
sandbox.stub(element.$.restAPI, 'getAccountCapabilities', () => { sandbox.stub(element.$.restAPI, 'getAccountCapabilities', () => {
return Promise.resolve({ return Promise.resolve({
createGroup: true, createGroup: true,
@ -181,10 +181,10 @@ limitations under the License.
return Promise.resolve({_id: 1}); return Promise.resolve({_id: 1});
}); });
sandbox.stub(element, 'reload'); sandbox.stub(element, 'reload');
element.params = {project: 'Test Project', adminView: 'gr-project'}; element.params = {repo: 'Test Repo', adminView: 'gr-repo'};
assert.equal(element.reload.callCount, 1); assert.equal(element.reload.callCount, 1);
element.params = {project: 'Test Project 2', element.params = {repo: 'Test Repo 2',
adminView: 'gr-project'}; adminView: 'gr-repo'};
assert.equal(element.reload.callCount, 2); assert.equal(element.reload.callCount, 2);
}); });
@ -235,34 +235,34 @@ limitations under the License.
return element.reload(); return element.reload();
}); });
suite('projects', () => { suite('repos', () => {
setup(() => { setup(() => {
stub('gr-project-access', { stub('gr-repo-access', {
_projectChanged: () => {}, _repoChanged: () => {},
}); });
}); });
test('project list', done => { test('repo list', done => {
element.params = { element.params = {
view: Gerrit.Nav.View.ADMIN, view: Gerrit.Nav.View.ADMIN,
adminView: 'gr-project-list', adminView: 'gr-repo-list',
openCreateModal: false, openCreateModal: false,
}; };
flush(() => { flush(() => {
const selected = element.$$('gr-page-nav .selected'); const selected = element.$$('gr-page-nav .selected');
assert.isOk(selected); assert.isOk(selected);
assert.equal(selected.textContent.trim(), 'Projects'); assert.equal(selected.textContent.trim(), 'Repositories');
done(); done();
}); });
}); });
test('project', done => { test('repo', done => {
element.params = { element.params = {
view: Gerrit.Nav.View.ADMIN, view: Gerrit.Nav.View.ADMIN,
project: 'foo', project: 'foo',
adminView: 'gr-project', adminView: 'gr-repo',
}; };
element._projectName = 'foo'; element._repoName = 'foo';
element.reload().then(() => { element.reload().then(() => {
flush(() => { flush(() => {
const selected = element.$$('gr-page-nav .selected'); const selected = element.$$('gr-page-nav .selected');
@ -273,14 +273,14 @@ limitations under the License.
}); });
}); });
test('project access', done => { test('repo access', done => {
element.params = { element.params = {
view: Gerrit.Nav.View.ADMIN, view: Gerrit.Nav.View.ADMIN,
adminView: 'gr-project-access', adminView: 'gr-repo-access',
detailType: 'access', detailType: 'access',
project: 'foo', repo: 'foo',
}; };
element._projectName = 'foo'; element._repoName = 'foo';
element.reload().then(() => { element.reload().then(() => {
flush(() => { flush(() => {
const selected = element.$$('gr-page-nav .selected'); const selected = element.$$('gr-page-nav .selected');

View File

@ -90,7 +90,7 @@ limitations under the License.
<input <input
type="checkbox" type="checkbox"
id="privateChangeCheckBox" id="privateChangeCheckBox"
checked$="[[_projectConfig.private_by_default.inherited_value]]"> checked$="[[_repoConfig.private_by_default.inherited_value]]">
</section> </section>
<section> <section>
<label for="wipChangeCheckBox">WIP Change</label> <label for="wipChangeCheckBox">WIP Change</label>

View File

@ -21,16 +21,16 @@
is: 'gr-create-change-dialog', is: 'gr-create-change-dialog',
properties: { properties: {
projectName: String, repoName: String,
branch: String, branch: String,
/** @type {?} */ /** @type {?} */
_projectConfig: Object, _repoConfig: Object,
subject: String, subject: String,
topic: String, topic: String,
_query: { _query: {
type: Function, type: Function,
value() { value() {
return this._getProjectBranchesSuggestions.bind(this); return this._getRepoBranchesSuggestions.bind(this);
}, },
}, },
canCreate: { canCreate: {
@ -46,8 +46,8 @@
], ],
attached() { attached() {
this.$.restAPI.getProjectConfig(this.projectName).then(config => { this.$.restAPI.getProjectConfig(this.repoName).then(config => {
this._projectConfig = config; this._repoConfig = config;
}); });
}, },
@ -62,7 +62,7 @@
handleCreateChange() { handleCreateChange() {
const isPrivate = this.$.privateChangeCheckBox.checked; const isPrivate = this.$.privateChangeCheckBox.checked;
const isWip = this.$.wipChangeCheckBox.checked; const isWip = this.$.wipChangeCheckBox.checked;
return this.$.restAPI.createChange(this.projectName, this.branch, return this.$.restAPI.createChange(this.repoName, this.branch,
this.subject, this.topic, isPrivate, isWip) this.subject, this.topic, isPrivate, isWip)
.then(changeCreated => { .then(changeCreated => {
if (!changeCreated) { if (!changeCreated) {
@ -72,12 +72,12 @@
}); });
}, },
_getProjectBranchesSuggestions(input) { _getRepoBranchesSuggestions(input) {
if (input.startsWith(REF_PREFIX)) { if (input.startsWith(REF_PREFIX)) {
input = input.substring(REF_PREFIX.length); input = input.substring(REF_PREFIX.length);
} }
return this.$.restAPI.getProjectBranches( return this.$.restAPI.getRepoBranches(
input, this.projectName, SUGGESTIONS_LIMIT).then(response => { input, this.repoName, SUGGESTIONS_LIMIT).then(response => {
const branches = []; const branches = [];
let branch; let branch;
for (const key in response) { for (const key in response) {

View File

@ -40,7 +40,7 @@ limitations under the License.
sandbox = sinon.sandbox.create(); sandbox = sinon.sandbox.create();
stub('gr-rest-api-interface', { stub('gr-rest-api-interface', {
getLoggedIn() { return Promise.resolve(true); }, getLoggedIn() { return Promise.resolve(true); },
getProjectBranches(input) { getRepoBranches(input) {
if (input.startsWith('test')) { if (input.startsWith('test')) {
return Promise.resolve([ return Promise.resolve([
{ {
@ -55,8 +55,8 @@ limitations under the License.
}, },
}); });
element = fixture('basic'); element = fixture('basic');
element.projectName = 'test-project'; element.repoName = 'test-repo';
element._projectConfig = { element._repoConfig = {
private_by_default: {}, private_by_default: {},
}; };
}); });
@ -66,7 +66,7 @@ limitations under the License.
}); });
test('new change created with private', () => { test('new change created with private', () => {
element._projectConfig = { element._repoConfig = {
private_by_default: { private_by_default: {
inherited_value: true, inherited_value: true,
}, },
@ -77,7 +77,6 @@ limitations under the License.
topic: 'test-topic', topic: 'test-topic',
subject: 'first change created with polygerrit ui', subject: 'first change created with polygerrit ui',
work_in_progress: false, work_in_progress: false,
project: element.projectName,
}; };
const saveStub = sandbox.stub(element.$.restAPI, const saveStub = sandbox.stub(element.$.restAPI,
@ -85,7 +84,6 @@ limitations under the License.
return Promise.resolve({}); return Promise.resolve({});
}); });
element.project = element.projectName;
element.branch = 'test-branch'; element.branch = 'test-branch';
element.topic = 'test-topic'; element.topic = 'test-topic';
element.subject = 'first change created with polygerrit ui'; element.subject = 'first change created with polygerrit ui';
@ -105,7 +103,6 @@ limitations under the License.
branch: 'test-branch', branch: 'test-branch',
topic: 'test-topic', topic: 'test-topic',
subject: 'first change created with polygerrit ui', subject: 'first change created with polygerrit ui',
project: element.projectName,
}; };
const saveStub = sandbox.stub(element.$.restAPI, const saveStub = sandbox.stub(element.$.restAPI,
@ -113,7 +110,6 @@ limitations under the License.
return Promise.resolve({}); return Promise.resolve({});
}); });
element.project = element.projectName;
element.branch = 'test-branch'; element.branch = 'test-branch';
element.topic = 'test-topic'; element.topic = 'test-topic';
element.subject = 'first change created with polygerrit ui'; element.subject = 'first change created with polygerrit ui';
@ -129,15 +125,15 @@ limitations under the License.
}); });
}); });
test('_getProjectBranchesSuggestions empty', done => { test('_getRepoBranchesSuggestions empty', done => {
element._getProjectBranchesSuggestions('nonexistent').then(branches => { element._getRepoBranchesSuggestions('nonexistent').then(branches => {
assert.equal(branches.length, 0); assert.equal(branches.length, 0);
done(); done();
}); });
}); });
test('_getProjectBranchesSuggestions non-empty', done => { test('_getRepoBranchesSuggestions non-empty', done => {
element._getProjectBranchesSuggestions('test-branch').then(branches => { element._getRepoBranchesSuggestions('test-branch').then(branches => {
assert.equal(branches.length, 1); assert.equal(branches.length, 1);
assert.equal(branches[0].name, 'test-branch'); assert.equal(branches[0].name, 'test-branch');
done(); done();

View File

@ -24,7 +24,7 @@
properties: { properties: {
detailType: String, detailType: String,
projectName: String, repoName: String,
hasNewItemName: { hasNewItemName: {
type: Boolean, type: Boolean,
notify: true, notify: true,
@ -51,18 +51,18 @@
_computeItemUrl(project) { _computeItemUrl(project) {
if (this.itemDetail === DETAIL_TYPES.branches) { if (this.itemDetail === DETAIL_TYPES.branches) {
return this.getBaseUrl() + '/admin/projects/' + return this.getBaseUrl() + '/admin/repos/' +
this.encodeURL(this.projectName, true) + ',branches'; this.encodeURL(this.repoName, true) + ',branches';
} else if (this.itemDetail === DETAIL_TYPES.tags) { } else if (this.itemDetail === DETAIL_TYPES.tags) {
return this.getBaseUrl() + '/admin/projects/' + return this.getBaseUrl() + '/admin/repos/' +
this.encodeURL(this.projectName, true) + ',tags'; this.encodeURL(this.repoName, true) + ',tags';
} }
}, },
handleCreateItem() { handleCreateItem() {
const USE_HEAD = this._itemRevision ? this._itemRevision : 'HEAD'; const USE_HEAD = this._itemRevision ? this._itemRevision : 'HEAD';
if (this.itemDetail === DETAIL_TYPES.branches) { if (this.itemDetail === DETAIL_TYPES.branches) {
return this.$.restAPI.createProjectBranch(this.projectName, return this.$.restAPI.createRepoBranch(this.repoName,
this._itemName, {revision: USE_HEAD}) this._itemName, {revision: USE_HEAD})
.then(itemRegistered => { .then(itemRegistered => {
if (itemRegistered.status === 201) { if (itemRegistered.status === 201) {
@ -70,7 +70,7 @@
} }
}); });
} else if (this.itemDetail === DETAIL_TYPES.tags) { } else if (this.itemDetail === DETAIL_TYPES.tags) {
return this.$.restAPI.createProjectTag(this.projectName, return this.$.restAPI.createRepoTag(this.repoName,
this._itemName, this._itemName,
{revision: USE_HEAD, message: this._itemAnnotation || null}) {revision: USE_HEAD, message: this._itemAnnotation || null})
.then(itemRegistered => { .then(itemRegistered => {

View File

@ -49,7 +49,7 @@ limitations under the License.
}); });
test('branch created', () => { test('branch created', () => {
sandbox.stub(element.$.restAPI, 'createProjectBranch', () => { sandbox.stub(element.$.restAPI, 'createRepoBranch', () => {
return Promise.resolve({}); return Promise.resolve({});
}); });
@ -69,7 +69,7 @@ limitations under the License.
}); });
test('tag created', () => { test('tag created', () => {
sandbox.stub(element.$.restAPI, 'createProjectTag', () => { sandbox.stub(element.$.restAPI, 'createRepoTag', () => {
return Promise.resolve({}); return Promise.resolve({});
}); });
@ -89,7 +89,7 @@ limitations under the License.
}); });
test('tag created with annotations', () => { test('tag created with annotations', () => {
sandbox.stub(element.$.restAPI, 'createProjectTag', () => { sandbox.stub(element.$.restAPI, 'createRepoTag', () => {
return Promise.resolve({}); return Promise.resolve({});
}); });

View File

@ -26,7 +26,7 @@ limitations under the License.
<link rel="import" href="../../shared/gr-rest-api-interface/gr-rest-api-interface.html"> <link rel="import" href="../../shared/gr-rest-api-interface/gr-rest-api-interface.html">
<link rel="import" href="../../shared/gr-select/gr-select.html"> <link rel="import" href="../../shared/gr-select/gr-select.html">
<dom-module id="gr-create-project-dialog"> <dom-module id="gr-create-repo-dialog">
<template> <template>
<style include="shared-styles"></style> <style include="shared-styles"></style>
<style include="gr-form-styles"> <style include="gr-form-styles">
@ -52,18 +52,18 @@ limitations under the License.
<div class="gr-form-styles"> <div class="gr-form-styles">
<div id="form"> <div id="form">
<section> <section>
<span class="title">Project name</span> <span class="title">Repositories name</span>
<input is="iron-input" <input is="iron-input"
id="projectNameInput" id="repoNameInput"
autocomplete="on" autocomplete="on"
bind-value="{{_projectConfig.name}}"> bind-value="{{_repoConfig.name}}">
</section> </section>
<section> <section>
<span class="title">Rights inherit from</span> <span class="title">Rights inherit from</span>
<span class="value"> <span class="value">
<gr-autocomplete <gr-autocomplete
id="rightsInheritFromInput" id="rightsInheritFromInput"
text="{{_projectConfig.parent}}" text="{{_repoConfig.parent}}"
query="[[_query]]" query="[[_query]]"
placeholder="Optional, defaults to 'All-Projects'"> placeholder="Optional, defaults to 'All-Projects'">
</gr-autocomplete> </gr-autocomplete>
@ -74,7 +74,7 @@ limitations under the License.
<span class="value"> <span class="value">
<gr-select <gr-select
id="initalCommit" id="initalCommit"
bind-value="{{_projectConfig.create_empty_commit}}"> bind-value="{{_repoConfig.create_empty_commit}}">
<select> <select>
<option value="false">False</option> <option value="false">False</option>
<option value="true">True</option> <option value="true">True</option>
@ -83,12 +83,12 @@ limitations under the License.
</span> </span>
</section> </section>
<section> <section>
<span class="title">Only serve as parent for other projects</span> <span class="title">Only serve as parent for other repositories</span>
<span class="value"> <span class="value">
<gr-select <gr-select
id="parentProject" id="parentRepo"
is="gr-select" is="gr-select"
bind-value="{{_projectConfig.permissions_only}}"> bind-value="{{_repoConfig.permissions_only}}">
<select> <select>
<option value="false">False</option> <option value="false">False</option>
<option value="true">True</option> <option value="true">True</option>
@ -100,5 +100,5 @@ limitations under the License.
</div> </div>
<gr-rest-api-interface id="restAPI"></gr-rest-api-interface> <gr-rest-api-interface id="restAPI"></gr-rest-api-interface>
</template> </template>
<script src="gr-create-project-dialog.js"></script> <script src="gr-create-repo-dialog.js"></script>
</dom-module> </dom-module>

View File

@ -15,18 +15,18 @@
'use strict'; 'use strict';
Polymer({ Polymer({
is: 'gr-create-project-dialog', is: 'gr-create-repo-dialog',
properties: { properties: {
params: Object, params: Object,
hasNewProjectName: { hasNewRepoName: {
type: Boolean, type: Boolean,
notify: true, notify: true,
value: false, value: false,
}, },
/** @type {?} */ /** @type {?} */
_projectConfig: { _repoConfig: {
type: Object, type: Object,
value: () => { value: () => {
// Set default values for dropdowns. // Set default values for dropdowns.
@ -36,7 +36,7 @@
}; };
}, },
}, },
_projectCreated: { _repoCreated: {
type: Boolean, type: Boolean,
value: false, value: false,
}, },
@ -44,13 +44,13 @@
_query: { _query: {
type: Function, type: Function,
value() { value() {
return this._getProjectSuggestions.bind(this); return this._getRepoSuggestions.bind(this);
}, },
}, },
}, },
observers: [ observers: [
'_updateProjectName(_projectConfig.name)', '_updateRepoName(_repoConfig.name)',
], ],
behaviors: [ behaviors: [
@ -58,37 +58,37 @@
Gerrit.URLEncodingBehavior, Gerrit.URLEncodingBehavior,
], ],
_computeProjectUrl(projectName) { _computeRepoUrl(repoName) {
return this.getBaseUrl() + '/admin/projects/' + return this.getBaseUrl() + '/admin/repos/' +
this.encodeURL(projectName, true); this.encodeURL(repoName, true);
}, },
_updateProjectName(name) { _updateRepoName(name) {
this.hasNewProjectName = !!name; this.hasNewRepoName = !!name;
}, },
handleCreateProject() { handleCreateRepo() {
return this.$.restAPI.createProject(this._projectConfig) return this.$.restAPI.createRepo(this._repoConfig)
.then(projectRegistered => { .then(repoRegistered => {
if (projectRegistered.status === 201) { if (repoRegistered.status === 201) {
this._projectCreated = true; this._repoCreated = true;
page.show(this._computeProjectUrl(this._projectConfig.name)); page.show(this._computeRepoUrl(this._repoConfig.name));
} }
}); });
}, },
_getProjectSuggestions(input) { _getRepoSuggestions(input) {
return this.$.restAPI.getSuggestedProjects(input) return this.$.restAPI.getSuggestedProjects(input)
.then(response => { .then(response => {
const projects = []; const repos = [];
for (const key in response) { for (const key in response) {
if (!response.hasOwnProperty(key)) { continue; } if (!response.hasOwnProperty(key)) { continue; }
projects.push({ repos.push({
name: key, name: key,
value: response[key], value: response[key],
}); });
} }
return projects; return repos;
}); });
}, },
}); });

View File

@ -16,23 +16,23 @@ limitations under the License.
--> -->
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes"> <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-create-project-dialog</title> <title>gr-create-repo-dialog</title>
<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script> <script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
<script src="../../../bower_components/web-component-tester/browser.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="../../../test/common-test-setup.html"/>
<link rel="import" href="gr-create-project-dialog.html"> <link rel="import" href="gr-create-repo-dialog.html">
<script>void(0);</script> <script>void(0);</script>
<test-fixture id="basic"> <test-fixture id="basic">
<template> <template>
<gr-create-project-dialog></gr-create-project-dialog> <gr-create-repo-dialog></gr-create-repo-dialog>
</template> </template>
</test-fixture> </test-fixture>
<script> <script>
suite('gr-create-project-dialog tests', () => { suite('gr-create-repo-dialog tests', () => {
let element; let element;
let sandbox; let sandbox;
@ -50,43 +50,43 @@ limitations under the License.
test('default values are populated', () => { test('default values are populated', () => {
assert.isFalse(element.$.initalCommit.bindValue); assert.isFalse(element.$.initalCommit.bindValue);
assert.isFalse(element.$.parentProject.bindValue); assert.isFalse(element.$.parentRepo.bindValue);
}); });
test('project created', done => { test('repo created', done => {
const configInputObj = { const configInputObj = {
name: 'test-project', name: 'test-repo',
create_empty_commit: true, create_empty_commit: true,
parent: 'All-Project', parent: 'All-Project',
permissions_only: false, permissions_only: false,
}; };
const saveStub = sandbox.stub(element.$.restAPI, const saveStub = sandbox.stub(element.$.restAPI,
'createProject', () => { 'createRepo', () => {
return Promise.resolve({}); return Promise.resolve({});
}); });
assert.isFalse(element.hasNewProjectName); assert.isFalse(element.hasNewRepoName);
element._projectConfig = { element._repoConfig = {
name: 'test-project', name: 'test-repo',
create_empty_commit: true, create_empty_commit: true,
parent: 'All-Project', parent: 'All-Project',
permissions_only: false, permissions_only: false,
}; };
element.$.projectNameInput.bindValue = configInputObj.name; element.$.repoNameInput.bindValue = configInputObj.name;
element.$.rightsInheritFromInput.bindValue = configInputObj.parent; element.$.rightsInheritFromInput.bindValue = configInputObj.parent;
element.$.initalCommit.bindValue = element.$.initalCommit.bindValue =
configInputObj.create_empty_commit; configInputObj.create_empty_commit;
element.$.parentProject.bindValue = element.$.parentRepo.bindValue =
configInputObj.permissions_only; configInputObj.permissions_only;
assert.isTrue(element.hasNewProjectName); assert.isTrue(element.hasNewRepoName);
assert.deepEqual(element._projectConfig, configInputObj); assert.deepEqual(element._repoConfig, configInputObj);
element.handleCreateProject().then(() => { element.handleCreateRepo().then(() => {
assert.isTrue(saveStub.lastCall.calledWithExactly(configInputObj)); assert.isTrue(saveStub.lastCall.calledWithExactly(configInputObj));
done(); done();
}); });

View File

@ -28,7 +28,7 @@ limitations under the License.
<script src="../../../scripts/util.js"></script> <script src="../../../scripts/util.js"></script>
<dom-module id="gr-project-access"> <dom-module id="gr-repo-access">
<template> <template>
<style include="shared-styles"> <style include="shared-styles">
.gwtLink { .gwtLink {
@ -82,5 +82,5 @@ limitations under the License.
</main> </main>
<gr-rest-api-interface id="restAPI"></gr-rest-api-interface> <gr-rest-api-interface id="restAPI"></gr-rest-api-interface>
</template> </template>
<script src="gr-project-access.js"></script> <script src="gr-repo-access.js"></script>
</dom-module> </dom-module>

View File

@ -56,12 +56,12 @@
Polymer({ Polymer({
is: 'gr-project-access', is: 'gr-repo-access',
properties: { properties: {
project: { repo: {
type: String, type: String,
observer: '_projectChanged', observer: '_repoChanged',
}, },
// The current path // The current path
path: String, path: String,
@ -148,15 +148,15 @@
}, },
/** /**
* @param {string} project * @param {string} repo
* @return {!Promise} * @return {!Promise}
*/ */
_projectChanged(project) { _repoChanged(repo) {
if (!project) { return Promise.resolve(); } if (!repo) { return Promise.resolve(); }
const promises = []; const promises = [];
// Always reset sections when a project changes. // Always reset sections when a project changes.
this._sections = []; this._sections = [];
promises.push(this.$.restAPI.getProjectAccessRights(project).then(res => { promises.push(this.$.restAPI.getRepoAccessRights(repo).then(res => {
this._inheritsFrom = res.inherits_from; this._inheritsFrom = res.inherits_from;
this._local = res.local; this._local = res.local;
this._groups = res.groups; this._groups = res.groups;
@ -167,7 +167,7 @@
return res; return res;
})); }));
promises.push(this.$.restAPI.getProject(project).then(res => { promises.push(this.$.restAPI.getRepo(repo).then(res => {
return res.labels; return res.labels;
})); }));
@ -296,9 +296,9 @@
return isAdmin ? 'admin' : ''; return isAdmin ? 'admin' : '';
}, },
_computeParentHref(projectName) { _computeParentHref(repoName) {
return this.getBaseUrl() + return this.getBaseUrl() +
`/admin/projects/${this.encodeURL(projectName, true)},access`; `/admin/repos/${this.encodeURL(repoName, true)},access`;
}, },
}); });
})(); })();

View File

@ -16,24 +16,24 @@ limitations under the License.
--> -->
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes"> <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-project-access</title> <title>gr-repo-access</title>
<script src="../../../bower_components/page/page.js"></script> <script src="../../../bower_components/page/page.js"></script>
<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script> <script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
<script src="../../../bower_components/web-component-tester/browser.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="../../../test/common-test-setup.html"/>
<link rel="import" href="gr-project-access.html"> <link rel="import" href="gr-repo-access.html">
<script>void(0);</script> <script>void(0);</script>
<test-fixture id="basic"> <test-fixture id="basic">
<template> <template>
<gr-project-access></gr-project-access> <gr-repo-access></gr-repo-access>
</template> </template>
</test-fixture> </test-fixture>
<script> <script>
suite('gr-project-access tests', () => { suite('gr-repo-access tests', () => {
let element; let element;
let sandbox; let sandbox;
@ -71,12 +71,12 @@ limitations under the License.
}, },
}, },
}; };
const projectRes = { const repoRes = {
labels: { labels: {
'Code-Review': {}, 'Code-Review': {},
}, },
}; };
const projectAccessInput = { const repoAccessInput = {
add: { add: {
'refs/*': { 'refs/*': {
permissions: { permissions: {
@ -110,13 +110,13 @@ limitations under the License.
sandbox.restore(); sandbox.restore();
}); });
test('_projectChanged called when project name changes', () => { test('_repoChanged called when repo name changes', () => {
sandbox.stub(element, '_projectChanged'); sandbox.stub(element, '_repoChanged');
element.project = 'New Project'; element.repo = 'New Repo';
assert.isTrue(element._projectChanged.called); assert.isTrue(element._repoChanged.called);
}); });
test('_projectChanged', done => { test('_repoChanged', done => {
const capabilitiesRes = { const capabilitiesRes = {
accessDatabase: { accessDatabase: {
id: 'accessDatabase', id: 'accessDatabase',
@ -129,31 +129,31 @@ limitations under the License.
}; };
const accessStub = sandbox.stub(element.$.restAPI, const accessStub = sandbox.stub(element.$.restAPI,
'getProjectAccessRights'); 'getRepoAccessRights');
accessStub.withArgs('New Project').returns(Promise.resolve(accessRes)); accessStub.withArgs('New Repo').returns(Promise.resolve(accessRes));
accessStub.withArgs('Another New Project') accessStub.withArgs('Another New Repo')
.returns(Promise.resolve(accessRes2)); .returns(Promise.resolve(accessRes2));
const capabilitiesStub = sandbox.stub(element.$.restAPI, const capabilitiesStub = sandbox.stub(element.$.restAPI,
'getCapabilities'); 'getCapabilities');
capabilitiesStub.returns(Promise.resolve(capabilitiesRes)); capabilitiesStub.returns(Promise.resolve(capabilitiesRes));
const projectStub = sandbox.stub(element.$.restAPI, 'getProject').returns( const repoStub = sandbox.stub(element.$.restAPI, 'getRepo').returns(
Promise.resolve(projectRes)); Promise.resolve(repoRes));
const adminStub = sandbox.stub(element.$.restAPI, 'getIsAdmin').returns( const adminStub = sandbox.stub(element.$.restAPI, 'getIsAdmin').returns(
Promise.resolve(true)); Promise.resolve(true));
element._projectChanged('New Project').then(() => { element._repoChanged('New Repo').then(() => {
assert.isTrue(accessStub.called); assert.isTrue(accessStub.called);
assert.isTrue(capabilitiesStub.called); assert.isTrue(capabilitiesStub.called);
assert.isTrue(projectStub.called); assert.isTrue(repoStub.called);
assert.isTrue(adminStub.called); assert.isTrue(adminStub.called);
assert.isNotOk(element._inheritsFrom); assert.isNotOk(element._inheritsFrom);
assert.deepEqual(element._local, accessRes.local); assert.deepEqual(element._local, accessRes.local);
assert.deepEqual(element._sections, assert.deepEqual(element._sections,
element.toSortedArray(accessRes.local)); element.toSortedArray(accessRes.local));
assert.deepEqual(element._labels, projectRes.labels); assert.deepEqual(element._labels, repoRes.labels);
return element._projectChanged('Another New Project'); return element._repoChanged('Another New Repo');
}) })
.then(() => { .then(() => {
assert.deepEqual(element._sections, assert.deepEqual(element._sections,
@ -162,7 +162,7 @@ limitations under the License.
}); });
}); });
test('_projectChanged when project changes to undefined returns', done => { test('_repoChanged when repo changes to undefined returns', done => {
const capabilitiesRes = { const capabilitiesRes = {
accessDatabase: { accessDatabase: {
id: 'accessDatabase', id: 'accessDatabase',
@ -182,30 +182,30 @@ limitations under the License.
}, },
}, },
}; };
const projectRes = { const repoRes = {
labels: { labels: {
'Code-Review': {}, 'Code-Review': {},
}, },
}; };
const accessStub = sandbox.stub(element.$.restAPI, const accessStub = sandbox.stub(element.$.restAPI,
'getProjectAccessRights').returns(Promise.resolve(accessRes)); 'getRepoAccessRights').returns(Promise.resolve(accessRes));
const capabilitiesStub = sandbox.stub(element.$.restAPI, const capabilitiesStub = sandbox.stub(element.$.restAPI,
'getCapabilities').returns(Promise.resolve(capabilitiesRes)); 'getCapabilities').returns(Promise.resolve(capabilitiesRes));
const projectStub = sandbox.stub(element.$.restAPI, 'getProject').returns( const repoStub = sandbox.stub(element.$.restAPI, 'getRepo').returns(
Promise.resolve(projectRes)); Promise.resolve(repoRes));
element._projectChanged().then(() => { element._repoChanged().then(() => {
assert.isFalse(accessStub.called); assert.isFalse(accessStub.called);
assert.isFalse(capabilitiesStub.called); assert.isFalse(capabilitiesStub.called);
assert.isFalse(projectStub.called); assert.isFalse(repoStub.called);
done(); done();
}); });
}); });
test('_computeParentHref', () => { test('_computeParentHref', () => {
const projectName = 'test-project'; const repoName = 'test-repo';
assert.equal(element._computeParentHref(projectName), assert.equal(element._computeParentHref(repoName),
'/admin/projects/test-project,access'); '/admin/repos/test-repo,access');
}); });
test('_computeAdminClass', () => { test('_computeAdminClass', () => {
@ -220,7 +220,7 @@ limitations under the License.
assert.isNotOk(Polymer.dom(element.root).querySelector('#inheritsFrom')); assert.isNotOk(Polymer.dom(element.root).querySelector('#inheritsFrom'));
assert.isFalse(element._computeParentHref.called); assert.isFalse(element._computeParentHref.called);
element._inheritsFrom = { element._inheritsFrom = {
name: 'another-project', name: 'another-repo',
}; };
flushAsynchronousOperations(); flushAsynchronousOperations();
assert.isOk(Polymer.dom(element.root).querySelector('#inheritsFrom')); assert.isOk(Polymer.dom(element.root).querySelector('#inheritsFrom'));
@ -313,22 +313,22 @@ limitations under the License.
assert.deepEqual(element._computeAddAndRemove(), {add: {}, remove: {}}); assert.deepEqual(element._computeAddAndRemove(), {add: {}, remove: {}});
const rules = element._getAllRules(); const rules = element._getAllRules();
rules[0]._modified = true; rules[0]._modified = true;
assert.deepEqual(element._computeAddAndRemove(), projectAccessInput); assert.deepEqual(element._computeAddAndRemove(), repoAccessInput);
}); });
test('_handleSaveForReview', done => { test('_handleSaveForReview', done => {
sandbox.stub(element.$.restAPI, 'getProjectAccessRights') sandbox.stub(element.$.restAPI, 'getRepoAccessRights')
.returns(Promise.resolve(accessRes)); .returns(Promise.resolve(accessRes));
sandbox.stub(element.$.restAPI, 'getProject') sandbox.stub(element.$.restAPI, 'getRepo')
.returns(Promise.resolve({})); .returns(Promise.resolve({}));
sandbox.stub(Gerrit.Nav, 'navigateToChange'); sandbox.stub(Gerrit.Nav, 'navigateToChange');
const saveForReviewStub = sandbox.stub(element.$.restAPI, const saveForReviewStub = sandbox.stub(element.$.restAPI,
'setProjectAccessRightsForReview') 'setProjectAccessRightsForReview')
.returns(Promise.resolve({_number: 1})); .returns(Promise.resolve({_number: 1}));
element.project = 'test-project'; element.repo = 'test-repo';
sandbox.stub(element, '_computeAddAndRemove') sandbox.stub(element, '_computeAddAndRemove')
.returns(projectAccessInput); .returns(repoAccessInput);
element._handleSaveForReview().then(() => { element._handleSaveForReview().then(() => {
assert.isTrue(saveForReviewStub.called); assert.isTrue(saveForReviewStub.called);
@ -339,4 +339,4 @@ limitations under the License.
}); });
}); });
}); });
</script> </script>

View File

@ -17,7 +17,7 @@ limitations under the License.
<link rel="import" href="../../../styles/shared-styles.html"> <link rel="import" href="../../../styles/shared-styles.html">
<link rel="import" href="../../shared/gr-button/gr-button.html"> <link rel="import" href="../../shared/gr-button/gr-button.html">
<dom-module id="gr-project-command"> <dom-module id="gr-repo-command">
<template> <template>
<style include="shared-styles"> <style include="shared-styles">
:host { :host {
@ -28,5 +28,5 @@ limitations under the License.
<h3>[[title]]</h3> <h3>[[title]]</h3>
<gr-button on-tap="_onCommandTap">[[title]]</gr-button> <gr-button on-tap="_onCommandTap">[[title]]</gr-button>
</template> </template>
<script src="gr-project-command.js"></script> <script src="gr-repo-command.js"></script>
</dom-module> </dom-module>

View File

@ -15,7 +15,7 @@
'use strict'; 'use strict';
Polymer({ Polymer({
is: 'gr-project-command', is: 'gr-repo-command',
properties: { properties: {
title: String, title: String,

View File

@ -16,23 +16,23 @@ limitations under the License.
--> -->
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes"> <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-project-command</title> <title>gr-repo-command</title>
<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script> <script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
<script src="../../../bower_components/web-component-tester/browser.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="../../../test/common-test-setup.html"/>
<link rel="import" href="gr-project-command.html"> <link rel="import" href="gr-repo-command.html">
<script>void(0);</script> <script>void(0);</script>
<test-fixture id="basic"> <test-fixture id="basic">
<template> <template>
<gr-project-command></gr-project-command> <gr-repo-command></gr-repo-command>
</template> </template>
</test-fixture> </test-fixture>
<script> <script>
suite('gr-project-command tests', () => { suite('gr-repo-command tests', () => {
let element; let element;
setup(() => { setup(() => {

View File

@ -25,9 +25,9 @@ limitations under the License.
<link rel="import" href="../../shared/gr-overlay/gr-overlay.html"> <link rel="import" href="../../shared/gr-overlay/gr-overlay.html">
<link rel="import" href="../../shared/gr-rest-api-interface/gr-rest-api-interface.html"> <link rel="import" href="../../shared/gr-rest-api-interface/gr-rest-api-interface.html">
<link rel="import" href="../gr-create-change-dialog/gr-create-change-dialog.html"> <link rel="import" href="../gr-create-change-dialog/gr-create-change-dialog.html">
<link rel="import" href="../gr-project-command/gr-project-command.html"> <link rel="import" href="../gr-repo-command/gr-repo-command.html">
<dom-module id="gr-project-commands"> <dom-module id="gr-repo-commands">
<template> <template>
<style include="shared-styles"> <style include="shared-styles">
main { main {
@ -45,26 +45,26 @@ limitations under the License.
</style> </style>
<style include="gr-form-styles"></style> <style include="gr-form-styles"></style>
<main class="gr-form-styles read-only"> <main class="gr-form-styles read-only">
<h1 id="Title">Project Commands</h1> <h1 id="Title">Repository Commands</h1>
<div id="loading" class$="[[_computeLoadingClass(_loading)]]">Loading...</div> <div id="loading" class$="[[_computeLoadingClass(_loading)]]">Loading...</div>
<div id="loadedContent" class$="[[_computeLoadingClass(_loading)]]"> <div id="loadedContent" class$="[[_computeLoadingClass(_loading)]]">
<h2 id="options">Command</h2> <h2 id="options">Command</h2>
<div id="form"> <div id="form">
<gr-project-command <gr-repo-command
title="Create Change" title="Create Change"
on-command-tap="_createNewChange"> on-command-tap="_createNewChange">
</gr-project-command> </gr-repo-command>
<gr-project-command <gr-repo-command
title="Run GC" title="Run GC"
hidden$="[[!_projectConfig.actions.gc.enabled]]" hidden$="[[!_repoConfig.actions.gc.enabled]]"
on-command-tap="_handleRunningGC"> on-command-tap="_handleRunningGC">
</gr-project-command> </gr-repo-command>
<gr-endpoint-decorator name="project-command"> <gr-endpoint-decorator name="repo-command">
<gr-endpoint-param name="config" value="[[_projectConfig]]"> <gr-endpoint-param name="config" value="[[_repoConfig]]">
</gr-endpoint-param> </gr-endpoint-param>
<gr-endpoint-param name="projectName" value="[[project]]"> <gr-endpoint-param name="repoName" value="[[repo]]">
</gr-endpoint-param> </gr-endpoint-param>
</gr-endpoint-decorator> </gr-endpoint-decorator>
</div> </div>
@ -84,11 +84,11 @@ limitations under the License.
<gr-create-change-dialog <gr-create-change-dialog
id="createNewChangeModal" id="createNewChangeModal"
can-create="{{_canCreate}}" can-create="{{_canCreate}}"
project-name="[[project]]"></gr-create-change-dialog> repo-name="[[repo]]"></gr-create-change-dialog>
</div> </div>
</gr-confirm-dialog> </gr-confirm-dialog>
</gr-overlay> </gr-overlay>
<gr-rest-api-interface id="restAPI"></gr-rest-api-interface> <gr-rest-api-interface id="restAPI"></gr-rest-api-interface>
</template> </template>
<script src="gr-project-commands.js"></script> <script src="gr-repo-commands.js"></script>
</dom-module> </dom-module>

View File

@ -17,32 +17,32 @@
const GC_MESSAGE = 'Garbage collection completed successfully.'; const GC_MESSAGE = 'Garbage collection completed successfully.';
Polymer({ Polymer({
is: 'gr-project-commands', is: 'gr-repo-commands',
properties: { properties: {
params: Object, params: Object,
project: String, repo: String,
_loading: { _loading: {
type: Boolean, type: Boolean,
value: true, value: true,
}, },
/** @type {?} */ /** @type {?} */
_projectConfig: Object, _repoConfig: Object,
_canCreate: Boolean, _canCreate: Boolean,
}, },
attached() { attached() {
this._loadProject(); this._loadRepo();
this.fire('title-change', {title: 'Project Commands'}); this.fire('title-change', {title: 'Repo Commands'});
}, },
_loadProject() { _loadRepo() {
if (!this.project) { return Promise.resolve(); } if (!this.repo) { return Promise.resolve(); }
return this.$.restAPI.getProjectConfig(this.project).then( return this.$.restAPI.getProjectConfig(this.repo).then(
config => { config => {
this._projectConfig = config; this._repoConfig = config;
this._loading = false; this._loading = false;
}); });
}, },
@ -56,7 +56,7 @@
}, },
_handleRunningGC() { _handleRunningGC() {
return this.$.restAPI.runProjectGC(this.project).then(response => { return this.$.restAPI.runRepoGC(this.repo).then(response => {
if (response.status === 200) { if (response.status === 200) {
this.dispatchEvent(new CustomEvent('show-alert', this.dispatchEvent(new CustomEvent('show-alert',
{detail: {message: GC_MESSAGE}, bubbles: true})); {detail: {message: GC_MESSAGE}, bubbles: true}));

View File

@ -16,24 +16,24 @@ limitations under the License.
--> -->
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes"> <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-project-commands</title> <title>gr-repo-commands</title>
<script src="../../../bower_components/page/page.js"></script> <script src="../../../bower_components/page/page.js"></script>
<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script> <script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
<script src="../../../bower_components/web-component-tester/browser.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="../../../test/common-test-setup.html"/>
<link rel="import" href="gr-project-commands.html"> <link rel="import" href="gr-repo-commands.html">
<script>void(0);</script> <script>void(0);</script>
<test-fixture id="basic"> <test-fixture id="basic">
<template> <template>
<gr-project-commands></gr-project-commands> <gr-repo-commands></gr-repo-commands>
</template> </template>
</test-fixture> </test-fixture>
<script> <script>
suite('gr-project-commands tests', () => { suite('gr-repo-commands tests', () => {
let element; let element;
let sandbox; let sandbox;

View File

@ -30,7 +30,7 @@ limitations under the License.
<link rel="import" href="../gr-create-pointer-dialog/gr-create-pointer-dialog.html"> <link rel="import" href="../gr-create-pointer-dialog/gr-create-pointer-dialog.html">
<link rel="import" href="../gr-confirm-delete-item-dialog/gr-confirm-delete-item-dialog.html"> <link rel="import" href="../gr-confirm-delete-item-dialog/gr-confirm-delete-item-dialog.html">
<dom-module id="gr-project-detail-list"> <dom-module id="gr-repo-detail-list">
<template> <template>
<style include="gr-form-styles"></style> <style include="gr-form-styles"></style>
<style include="shared-styles"> <style include="shared-styles">
@ -87,7 +87,7 @@ limitations under the License.
loading="[[_loading]]" loading="[[_loading]]"
offset="[[_offset]]" offset="[[_offset]]"
on-create-clicked="_handleCreateClicked" on-create-clicked="_handleCreateClicked"
path="[[_getPath(_project, detailType)]]"> path="[[_getPath(_repo, detailType)]]">
<table id="list" class="genericList gr-form-styles"> <table id="list" class="genericList gr-form-styles">
<tr class="headerRow"> <tr class="headerRow">
<th class="name topHeader">Name</th> <th class="name topHeader">Name</th>
@ -202,11 +202,11 @@ limitations under the License.
detail-type="[[_computeItemName(detailType)]]" detail-type="[[_computeItemName(detailType)]]"
has-new-item-name="{{_hasNewItemName}}" has-new-item-name="{{_hasNewItemName}}"
item-detail="[[detailType]]" item-detail="[[detailType]]"
project-name="[[_project]]"></gr-create-pointer-dialog> repo-name="[[_repo]]"></gr-create-pointer-dialog>
</div> </div>
</gr-confirm-dialog> </gr-confirm-dialog>
</gr-overlay> </gr-overlay>
<gr-rest-api-interface id="restAPI"></gr-rest-api-interface> <gr-rest-api-interface id="restAPI"></gr-rest-api-interface>
</template> </template>
<script src="gr-project-detail-list.js"></script> <script src="gr-repo-detail-list.js"></script>
</dom-module> </dom-module>

View File

@ -20,7 +20,7 @@
}; };
Polymer({ Polymer({
is: 'gr-project-detail-list', is: 'gr-repo-detail-list',
properties: { properties: {
/** /**
@ -52,7 +52,7 @@
* Offset of currently visible query results. * Offset of currently visible query results.
*/ */
_offset: Number, _offset: Number,
_project: Object, _repo: Object,
_items: Array, _items: Array,
/** /**
* Because we request one more than the projectsPerPage, _shownProjects * Because we request one more than the projectsPerPage, _shownProjects
@ -82,21 +82,21 @@
Gerrit.URLEncodingBehavior, Gerrit.URLEncodingBehavior,
], ],
_determineIfOwner(project) { _determineIfOwner(repo) {
return this.$.restAPI.getProjectAccess(project) return this.$.restAPI.getRepoAccess(repo)
.then(access => .then(access =>
this._isOwner = access && access[project].is_owner); this._isOwner = access && access[repo].is_owner);
}, },
_paramsChanged(params) { _paramsChanged(params) {
if (!params || !params.project) { return; } if (!params || !params.repo) { return; }
this._project = params.project; this._repo = params.repo;
this._getLoggedIn().then(loggedIn => { this._getLoggedIn().then(loggedIn => {
this._loggedIn = loggedIn; this._loggedIn = loggedIn;
if (loggedIn) { if (loggedIn) {
this._determineIfOwner(this._project); this._determineIfOwner(this._repo);
} }
}); });
@ -105,24 +105,24 @@
this._filter = this.getFilterValue(params); this._filter = this.getFilterValue(params);
this._offset = this.getOffsetValue(params); this._offset = this.getOffsetValue(params);
return this._getItems(this._filter, this._project, return this._getItems(this._filter, this._repo,
this._itemsPerPage, this._offset, this.detailType); this._itemsPerPage, this._offset, this.detailType);
}, },
_getItems(filter, project, itemsPerPage, offset, detailType) { _getItems(filter, repo, itemsPerPage, offset, detailType) {
this._loading = true; this._loading = true;
this._items = []; this._items = [];
Polymer.dom.flush(); Polymer.dom.flush();
if (detailType === DETAIL_TYPES.BRANCHES) { if (detailType === DETAIL_TYPES.BRANCHES) {
return this.$.restAPI.getProjectBranches( return this.$.restAPI.getRepoBranches(
filter, project, itemsPerPage, offset) .then(items => { filter, repo, itemsPerPage, offset) .then(items => {
if (!items) { return; } if (!items) { return; }
this._items = items; this._items = items;
this._loading = false; this._loading = false;
}); });
} else if (detailType === DETAIL_TYPES.TAGS) { } else if (detailType === DETAIL_TYPES.TAGS) {
return this.$.restAPI.getProjectTags( return this.$.restAPI.getRepoTags(
filter, project, itemsPerPage, offset) .then(items => { filter, repo, itemsPerPage, offset) .then(items => {
if (!items) { return; } if (!items) { return; }
this._items = items; this._items = items;
this._loading = false; this._loading = false;
@ -130,14 +130,14 @@
} }
}, },
_getPath(project) { _getPath(repo) {
return `/admin/projects/${this.encodeURL(project, false)},` + return `/admin/repos/${this.encodeURL(repo, false)},` +
`${this.detailType}`; `${this.detailType}`;
}, },
_computeWeblink(project) { _computeWeblink(repo) {
if (!project.web_links) { return ''; } if (!repo.web_links) { return ''; }
const webLinks = project.web_links; const webLinks = repo.web_links;
return webLinks.length ? webLinks : null; return webLinks.length ? webLinks : null;
}, },
@ -172,11 +172,11 @@
}, },
_handleSaveRevision(e) { _handleSaveRevision(e) {
this._setProjectHead(this._project, this._revisedRef, e); this._setRepoHead(this._repo, this._revisedRef, e);
}, },
_setProjectHead(project, ref, e) { _setRepoHead(repo, ref, e) {
return this.$.restAPI.setProjectHead(project, ref).then(res => { return this.$.restAPI.setRepoHead(repo, ref).then(res => {
if (res.status < 400) { if (res.status < 400) {
this._isEditing = false; this._isEditing = false;
e.model.set('item.revision', ref); e.model.set('item.revision', ref);
@ -195,22 +195,22 @@
_handleDeleteItemConfirm() { _handleDeleteItemConfirm() {
this.$.overlay.close(); this.$.overlay.close();
if (this.detailType === DETAIL_TYPES.BRANCHES) { if (this.detailType === DETAIL_TYPES.BRANCHES) {
return this.$.restAPI.deleteProjectBranches(this._project, return this.$.restAPI.deleteRepoBranches(this._repo,
this._refName) this._refName)
.then(itemDeleted => { .then(itemDeleted => {
if (itemDeleted.status === 204) { if (itemDeleted.status === 204) {
this._getItems( this._getItems(
this._filter, this._project, this._itemsPerPage, this._filter, this._repo, this._itemsPerPage,
this._offset, this.detailType); this._offset, this.detailType);
} }
}); });
} else if (this.detailType === DETAIL_TYPES.TAGS) { } else if (this.detailType === DETAIL_TYPES.TAGS) {
return this.$.restAPI.deleteProjectTags(this._project, return this.$.restAPI.deleteRepoTags(this._repo,
this._refName) this._refName)
.then(itemDeleted => { .then(itemDeleted => {
if (itemDeleted.status === 204) { if (itemDeleted.status === 204) {
this._getItems( this._getItems(
this._filter, this._project, this._itemsPerPage, this._filter, this._repo, this._itemsPerPage,
this._offset, this.detailType); this._offset, this.detailType);
} }
}); });

View File

@ -16,19 +16,19 @@ limitations under the License.
--> -->
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes"> <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-project-detail-list</title> <title>gr-repo-detail-list</title>
<script src="../../../bower_components/page/page.js"></script> <script src="../../../bower_components/page/page.js"></script>
<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script> <script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
<script src="../../../bower_components/web-component-tester/browser.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="../../../test/common-test-setup.html"/>
<link rel="import" href="gr-project-detail-list.html"> <link rel="import" href="gr-repo-detail-list.html">
<script>void(0);</script> <script>void(0);</script>
<test-fixture id="basic"> <test-fixture id="basic">
<template> <template>
<gr-project-detail-list></gr-project-detail-list> <gr-repo-detail-list></gr-repo-detail-list>
</template> </template>
</test-fixture> </test-fixture>
@ -83,7 +83,7 @@ limitations under the License.
sandbox.restore(); sandbox.restore();
}); });
suite('list of project branches', () => { suite('list of repo branches', () => {
setup(done => { setup(done => {
branches = [{ branches = [{
ref: 'HEAD', ref: 'HEAD',
@ -91,13 +91,13 @@ limitations under the License.
}].concat(_.times(25, branchGenerator)); }].concat(_.times(25, branchGenerator));
stub('gr-rest-api-interface', { stub('gr-rest-api-interface', {
getProjectBranches(num, project, offset) { getRepoBranches(num, project, offset) {
return Promise.resolve(branches); return Promise.resolve(branches);
}, },
}); });
const params = { const params = {
project: 'test', repo: 'test',
detailType: 'branches', detailType: 'branches',
}; };
@ -133,7 +133,7 @@ limitations under the License.
test('Edit HEAD button not admin', done => { test('Edit HEAD button not admin', done => {
sandbox.stub(element, '_getLoggedIn').returns(Promise.resolve(true)); sandbox.stub(element, '_getLoggedIn').returns(Promise.resolve(true));
sandbox.stub(element.$.restAPI, 'getProjectAccess').returns( sandbox.stub(element.$.restAPI, 'getRepoAccess').returns(
Promise.resolve({ Promise.resolve({
test: {is_owner: false}, test: {is_owner: false},
})); }));
@ -157,7 +157,7 @@ limitations under the License.
.querySelector('.revisionWithEditing'); .querySelector('.revisionWithEditing');
sandbox.stub(element, '_getLoggedIn').returns(Promise.resolve(true)); sandbox.stub(element, '_getLoggedIn').returns(Promise.resolve(true));
sandbox.stub(element.$.restAPI, 'getProjectAccess').returns( sandbox.stub(element.$.restAPI, 'getRepoAccess').returns(
Promise.resolve({ Promise.resolve({
test: {is_owner: true}, test: {is_owner: true},
})); }));
@ -206,7 +206,7 @@ limitations under the License.
// Change the ref to something else // Change the ref to something else
element._revisedRef = 'newRef'; element._revisedRef = 'newRef';
element._project = 'test'; element._repo = 'test';
assert.isFalse(saveBtn.disabled); assert.isFalse(saveBtn.disabled);
// Save button calls handleSave. since this is stubbed, the edit // Save button calls handleSave. since this is stubbed, the edit
@ -234,13 +234,13 @@ limitations under the License.
test('_handleSaveRevision with invalid rev', done => { test('_handleSaveRevision with invalid rev', done => {
const event = {model: {set: sandbox.stub()}}; const event = {model: {set: sandbox.stub()}};
element._isEditing = true; element._isEditing = true;
sandbox.stub(element.$.restAPI, 'setProjectHead').returns( sandbox.stub(element.$.restAPI, 'setRepoHead').returns(
Promise.resolve({ Promise.resolve({
status: 400, status: 400,
}) })
); );
element._setProjectHead('test', 'newRef', event).then(() => { element._setRepoHead('test', 'newRef', event).then(() => {
assert.isTrue(element._isEditing); assert.isTrue(element._isEditing);
assert.isFalse(event.model.set.called); assert.isFalse(event.model.set.called);
done(); done();
@ -250,13 +250,13 @@ limitations under the License.
test('_handleSaveRevision with valid rev', done => { test('_handleSaveRevision with valid rev', done => {
const event = {model: {set: sandbox.stub()}}; const event = {model: {set: sandbox.stub()}};
element._isEditing = true; element._isEditing = true;
sandbox.stub(element.$.restAPI, 'setProjectHead').returns( sandbox.stub(element.$.restAPI, 'setRepoHead').returns(
Promise.resolve({ Promise.resolve({
status: 200, status: 200,
}) })
); );
element._setProjectHead('test', 'newRef', event).then(() => { element._setRepoHead('test', 'newRef', event).then(() => {
assert.isFalse(element._isEditing); assert.isFalse(element._isEditing);
assert.isTrue(event.model.set.called); assert.isTrue(event.model.set.called);
done(); done();
@ -274,37 +274,37 @@ limitations under the License.
branches = _.times(25, branchGenerator); branches = _.times(25, branchGenerator);
stub('gr-rest-api-interface', { stub('gr-rest-api-interface', {
getProjectBranches(num, project, offset) { getRepoBranches(num, repo, offset) {
return Promise.resolve(branches); return Promise.resolve(branches);
}, },
}); });
const params = { const params = {
project: 'test', repo: 'test',
detailType: 'branches', detailType: 'branches',
}; };
element._paramsChanged(params).then(() => { flush(done); }); element._paramsChanged(params).then(() => { flush(done); });
}); });
test('_shownProjectsBranches', () => { test('_shownItems', () => {
assert.equal(element._shownItems.length, 25); assert.equal(element._shownItems.length, 25);
}); });
}); });
suite('filter', () => { suite('filter', () => {
test('_paramsChanged', done => { test('_paramsChanged', done => {
sandbox.stub(element.$.restAPI, 'getProjectBranches', () => { sandbox.stub(element.$.restAPI, 'getRepoBranches', () => {
return Promise.resolve(branches); return Promise.resolve(branches);
}); });
const params = { const params = {
detailType: 'branches', detailType: 'branches',
project: 'test', repo: 'test',
filter: 'test', filter: 'test',
offset: 25, offset: 25,
}; };
element._paramsChanged(params).then(() => { element._paramsChanged(params).then(() => {
assert.isTrue(element.$.restAPI.getProjectBranches.lastCall assert.isTrue(element.$.restAPI.getRepoBranches.lastCall
.calledWithExactly('test', 'test', 25, 25)); .calledWithExactly('test', 'test', 25, 25));
done(); done();
}); });
@ -329,18 +329,18 @@ limitations under the License.
sandbox.restore(); sandbox.restore();
}); });
suite('list of project tags', () => { suite('list of repo tags', () => {
setup(done => { setup(done => {
tags = _.times(26, tagGenerator); tags = _.times(26, tagGenerator);
stub('gr-rest-api-interface', { stub('gr-rest-api-interface', {
getProjectTags(num, project, offset) { getRepoTags(num, repo, offset) {
return Promise.resolve(tags); return Promise.resolve(tags);
}, },
}); });
const params = { const params = {
project: 'test', repo: 'test',
detailType: 'tags', detailType: 'tags',
}; };
@ -409,13 +409,13 @@ limitations under the License.
tags = _.times(25, tagGenerator); tags = _.times(25, tagGenerator);
stub('gr-rest-api-interface', { stub('gr-rest-api-interface', {
getProjectTags(num, project, offset) { getRepoTags(num, project, offset) {
return Promise.resolve(tags); return Promise.resolve(tags);
}, },
}); });
const params = { const params = {
project: 'test', repo: 'test',
detailType: 'tags', detailType: 'tags',
}; };
@ -429,17 +429,17 @@ limitations under the License.
suite('filter', () => { suite('filter', () => {
test('_paramsChanged', done => { test('_paramsChanged', done => {
sandbox.stub(element.$.restAPI, 'getProjectTags', () => { sandbox.stub(element.$.restAPI, 'getRepoTags', () => {
return Promise.resolve(tags); return Promise.resolve(tags);
}); });
const params = { const params = {
project: 'test', repo: 'test',
detailType: 'tags', detailType: 'tags',
filter: 'test', filter: 'test',
offset: 25, offset: 25,
}; };
element._paramsChanged(params).then(() => { element._paramsChanged(params).then(() => {
assert.isTrue(element.$.restAPI.getProjectTags.lastCall assert.isTrue(element.$.restAPI.getRepoTags.lastCall
.calledWithExactly('test', 'test', 25, 25)); .calledWithExactly('test', 'test', 25, 25));
done(); done();
}); });

View File

@ -23,26 +23,25 @@ limitations under the License.
<link rel="import" href="../../shared/gr-list-view/gr-list-view.html"> <link rel="import" href="../../shared/gr-list-view/gr-list-view.html">
<link rel="import" href="../../shared/gr-overlay/gr-overlay.html"> <link rel="import" href="../../shared/gr-overlay/gr-overlay.html">
<link rel="import" href="../../shared/gr-rest-api-interface/gr-rest-api-interface.html"> <link rel="import" href="../../shared/gr-rest-api-interface/gr-rest-api-interface.html">
<link rel="import" href="../gr-create-project-dialog/gr-create-project-dialog.html"> <link rel="import" href="../gr-create-repo-dialog/gr-create-repo-dialog.html">
<dom-module id="gr-repo-list">
<dom-module id="gr-project-list">
<template> <template>
<style include="shared-styles"></style> <style include="shared-styles"></style>
<style include="gr-table-styles"></style> <style include="gr-table-styles"></style>
<gr-list-view <gr-list-view
create-new=[[_createNewCapability]] create-new=[[_createNewCapability]]
filter="[[_filter]]" filter="[[_filter]]"
items-per-page="[[_projectsPerPage]]" items-per-page="[[_reposPerPage]]"
items="[[_projects]]" items="[[_repos]]"
loading="[[_loading]]" loading="[[_loading]]"
offset="[[_offset]]" offset="[[_offset]]"
on-create-clicked="_handleCreateClicked" on-create-clicked="_handleCreateClicked"
path="[[_path]]"> path="[[_path]]">
<table id="list" class="genericList"> <table id="list" class="genericList">
<tr class="headerRow"> <tr class="headerRow">
<th class="name topHeader">Project Name</th> <th class="name topHeader">Repository Name</th>
<th class="description topHeader">Project Description</th> <th class="description topHeader">Repository Description</th>
<th class="repositoryBrowser topHeader">Repository Browser</th> <th class="repositoryBrowser topHeader">Repository Browser</th>
<th class="readOnly topHeader">Read only</th> <th class="readOnly topHeader">Read only</th>
</tr> </tr>
@ -50,10 +49,10 @@ limitations under the License.
<td>Loading...</td> <td>Loading...</td>
</tr> </tr>
<tbody class$="[[computeLoadingClass(_loading)]]"> <tbody class$="[[computeLoadingClass(_loading)]]">
<template is="dom-repeat" items="[[_shownProjects]]"> <template is="dom-repeat" items="[[_shownRepos]]">
<tr class="table"> <tr class="table">
<td class="name"> <td class="name">
<a href$="[[_computeProjectUrl(item.name)]]">[[item.name]]</a> <a href$="[[_computeRepoUrl(item.name)]]">[[item.name]]</a>
</td> </td>
<td class="description">[[item.description]]</td> <td class="description">[[item.description]]</td>
<td class="repositoryBrowser"> <td class="repositoryBrowser">
@ -77,22 +76,22 @@ limitations under the License.
<gr-confirm-dialog <gr-confirm-dialog
id="createDialog" id="createDialog"
class="confirmDialog" class="confirmDialog"
disabled="[[!_hasNewProjectName]]" disabled="[[!_hasNewRepoName]]"
confirm-label="Create" confirm-label="Create"
on-confirm="_handleCreateProject" on-confirm="_handleCreateRepo"
on-cancel="_handleCloseCreate"> on-cancel="_handleCloseCreate">
<div class="header" slot="header"> <div class="header" slot="header">
Create Project Create Repository
</div> </div>
<div class="main" slot="main"> <div class="main" slot="main">
<gr-create-project-dialog <gr-create-repo-dialog
has-new-project-name="{{_hasNewProjectName}}" has-new-repo-name="{{_hasNewRepoName}}"
params="[[params]]" params="[[params]]"
id="createNewModal"></gr-create-project-dialog> id="createNewModal"></gr-create-repo-dialog>
</div> </div>
</gr-confirm-dialog> </gr-confirm-dialog>
</gr-overlay> </gr-overlay>
<gr-rest-api-interface id="restAPI"></gr-rest-api-interface> <gr-rest-api-interface id="restAPI"></gr-rest-api-interface>
</template> </template>
<script src="gr-project-list.js"></script> <script src="gr-repo-list.js"></script>
</dom-module> </dom-module>

View File

@ -15,7 +15,7 @@
'use strict'; 'use strict';
Polymer({ Polymer({
is: 'gr-project-list', is: 'gr-repo-list',
properties: { properties: {
/** /**
@ -33,25 +33,25 @@
_path: { _path: {
type: String, type: String,
readOnly: true, readOnly: true,
value: '/admin/projects', value: '/admin/repos',
}, },
_hasNewProjectName: Boolean, _hasNewRepoName: Boolean,
_createNewCapability: { _createNewCapability: {
type: Boolean, type: Boolean,
value: false, value: false,
}, },
_projects: Array, _repos: Array,
/** /**
* Because we request one more than the projectsPerPage, _shownProjects * Because we request one more than the projectsPerPage, _shownProjects
* maybe one less than _projects. * maybe one less than _projects.
* */ * */
_shownProjects: { _shownRepos: {
type: Array, type: Array,
computed: 'computeShownItems(_projects)', computed: 'computeShownItems(_repos)',
}, },
_projectsPerPage: { _reposPerPage: {
type: Number, type: Number,
value: 25, value: 25,
}, },
@ -68,8 +68,8 @@
], ],
attached() { attached() {
this._getCreateProjectCapability(); this._getCreateRepoCapability();
this.fire('title-change', {title: 'Projects'}); this.fire('title-change', {title: 'Repos'});
this._maybeOpenCreateOverlay(this.params); this._maybeOpenCreateOverlay(this.params);
}, },
@ -78,7 +78,7 @@
this._filter = this.getFilterValue(params); this._filter = this.getFilterValue(params);
this._offset = this.getOffsetValue(params); this._offset = this.getOffsetValue(params);
return this._getProjects(this._filter, this._projectsPerPage, return this._getRepos(this._filter, this._reposPerPage,
this._offset); this._offset);
}, },
@ -92,11 +92,11 @@
} }
}, },
_computeProjectUrl(name) { _computeRepoUrl(name) {
return this.getUrl(this._path + '/', name); return this.getUrl(this._path + '/', name);
}, },
_getCreateProjectCapability() { _getCreateRepoCapability() {
return this.$.restAPI.getAccount().then(account => { return this.$.restAPI.getAccount().then(account => {
if (!account) { return; } if (!account) { return; }
return this.$.restAPI.getAccountCapabilities(['createProject']) return this.$.restAPI.getAccountCapabilities(['createProject'])
@ -108,25 +108,23 @@
}); });
}, },
_getProjects(filter, projectsPerPage, offset) { _getRepos(filter, reposPerPage, offset) {
this._projects = []; this._repos = [];
return this.$.restAPI.getProjects(filter, projectsPerPage, offset) return this.$.restAPI.getRepos(filter, reposPerPage, offset)
.then(projects => { .then(repos => {
if (!projects) { if (!repos) { return; }
return; this._repos = Object.keys(repos)
}
this._projects = Object.keys(projects)
.map(key => { .map(key => {
const project = projects[key]; const repo = repos[key];
project.name = key; repo.name = key;
return project; return repo;
}); });
this._loading = false; this._loading = false;
}); });
}, },
_handleCreateProject() { _handleCreateRepo() {
this.$.createNewModal.handleCreateProject(); this.$.createNewModal.handleCreateRepo();
}, },
_handleCloseCreate() { _handleCloseCreate() {
@ -141,11 +139,9 @@
return item.state === 'READ_ONLY' ? 'Y' : ''; return item.state === 'READ_ONLY' ? 'Y' : '';
}, },
_computeWeblink(project) { _computeWeblink(repo) {
if (!project.web_links) { if (!repo.web_links) { return ''; }
return ''; const webLinks = repo.web_links;
}
const webLinks = project.web_links;
return webLinks.length ? webLinks : null; return webLinks.length ? webLinks : null;
}, },
}); });

View File

@ -16,25 +16,25 @@ limitations under the License.
--> -->
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes"> <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-project-list</title> <title>gr-repo-list</title>
<script src="../../../bower_components/page/page.js"></script> <script src="../../../bower_components/page/page.js"></script>
<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script> <script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
<script src="../../../bower_components/web-component-tester/browser.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="../../../test/common-test-setup.html"/>
<link rel="import" href="gr-project-list.html"> <link rel="import" href="gr-repo-list.html">
<script>void(0);</script> <script>void(0);</script>
<test-fixture id="basic"> <test-fixture id="basic">
<template> <template>
<gr-project-list></gr-project-list> <gr-repo-list></gr-repo-list>
</template> </template>
</test-fixture> </test-fixture>
<script> <script>
let counter; let counter;
const projectGenerator = () => { const repoGenerator = () => {
return { return {
id: `test${++counter}`, id: `test${++counter}`,
state: 'ACTIVE', state: 'ACTIVE',
@ -47,9 +47,9 @@ limitations under the License.
}; };
}; };
suite('gr-project-list tests', () => { suite('gr-repo-list tests', () => {
let element; let element;
let projects; let repos;
let sandbox; let sandbox;
let value; let value;
@ -63,26 +63,26 @@ limitations under the License.
sandbox.restore(); sandbox.restore();
}); });
suite('list with projects', () => { suite('list with repos', () => {
setup(done => { setup(done => {
projects = _.times(26, projectGenerator); repos = _.times(26, repoGenerator);
stub('gr-rest-api-interface', { stub('gr-rest-api-interface', {
getProjects(num, offset) { getRepos(num, offset) {
return Promise.resolve(projects); return Promise.resolve(repos);
}, },
}); });
element._paramsChanged(value).then(() => { flush(done); }); element._paramsChanged(value).then(() => { flush(done); });
}); });
test('test for test project in the list', done => { test('test for test repo in the list', done => {
flush(() => { flush(() => {
assert.equal(element._projects[1].id, 'test2'); assert.equal(element._repos[1].id, 'test2');
done(); done();
}); });
}); });
test('_shownProjects', () => { test('_shownRepos', () => {
assert.equal(element._shownProjects.length, 25); assert.equal(element._shownRepos.length, 25);
}); });
test('_maybeOpenCreateOverlay', () => { test('_maybeOpenCreateOverlay', () => {
@ -98,35 +98,35 @@ limitations under the License.
}); });
}); });
suite('list with less then 25 projects', () => { suite('list with less then 25 repos', () => {
setup(done => { setup(done => {
projects = _.times(25, projectGenerator); repos = _.times(25, repoGenerator);
stub('gr-rest-api-interface', { stub('gr-rest-api-interface', {
getProjects(num, offset) { getRepos(num, offset) {
return Promise.resolve(projects); return Promise.resolve(repos);
}, },
}); });
element._paramsChanged(value).then(() => { flush(done); }); element._paramsChanged(value).then(() => { flush(done); });
}); });
test('_shownProjects', () => { test('_shownRepos', () => {
assert.equal(element._shownProjects.length, 25); assert.equal(element._shownRepos.length, 25);
}); });
}); });
suite('filter', () => { suite('filter', () => {
test('_paramsChanged', done => { test('_paramsChanged', done => {
sandbox.stub(element.$.restAPI, 'getProjects', () => { sandbox.stub(element.$.restAPI, 'getRepos', () => {
return Promise.resolve(projects); return Promise.resolve(repos);
}); });
const value = { const value = {
filter: 'test', filter: 'test',
offset: 25, offset: 25,
}; };
element._paramsChanged(value).then(() => { element._paramsChanged(value).then(() => {
assert.isTrue(element.$.restAPI.getProjects.lastCall assert.isTrue(element.$.restAPI.getRepos.lastCall
.calledWithExactly('test', 25, 25)); .calledWithExactly('test', 25, 25));
done(); done();
}); });
@ -140,7 +140,7 @@ limitations under the License.
assert.equal(getComputedStyle(element.$.loading).display, 'block'); assert.equal(getComputedStyle(element.$.loading).display, 'block');
element._loading = false; element._loading = false;
element._projects = _.times(25, projectGenerator); element._repos = _.times(25, repoGenerator);
flushAsynchronousOperations(); flushAsynchronousOperations();
assert.equal(element.computeLoadingClass(element._loading), ''); assert.equal(element.computeLoadingClass(element._loading), '');
@ -161,10 +161,10 @@ limitations under the License.
assert.isTrue(openStub.called); assert.isTrue(openStub.called);
}); });
test('_handleCreateProject called when confirm fired', () => { test('_handleCreateRepo called when confirm fired', () => {
sandbox.stub(element, '_handleCreateProject'); sandbox.stub(element, '_handleCreateRepo');
element.$.createDialog.fire('confirm'); element.$.createDialog.fire('confirm');
assert.isTrue(element._handleCreateProject.called); assert.isTrue(element._handleCreateRepo.called);
}); });
test('_handleCloseCreate called when cancel fired', () => { test('_handleCloseCreate called when cancel fired', () => {

View File

@ -24,7 +24,7 @@ limitations under the License.
<link rel="import" href="../../../styles/gr-form-styles.html"> <link rel="import" href="../../../styles/gr-form-styles.html">
<link rel="import" href="../../../styles/shared-styles.html"> <link rel="import" href="../../../styles/shared-styles.html">
<dom-module id="gr-project"> <dom-module id="gr-repo">
<template> <template>
<style include="shared-styles"> <style include="shared-styles">
main { main {
@ -44,16 +44,16 @@ limitations under the License.
#loading:not(.loading) { #loading:not(.loading) {
display: none; display: none;
} }
.projectSettings { .repositorySettings {
display: none; display: none;
} }
.projectSettings.showConfig { .repositorySettings.showConfig {
display: block; display: block;
} }
</style> </style>
<style include="gr-form-styles"></style> <style include="gr-form-styles"></style>
<main class="gr-form-styles read-only"> <main class="gr-form-styles read-only">
<h1 id="Title">[[project]]</h1> <h1 id="Title">[[repo]]</h1>
<div id="loading" class$="[[_computeLoadingClass(_loading)]]">Loading...</div> <div id="loading" class$="[[_computeLoadingClass(_loading)]]">Loading...</div>
<div id="loadedContent" class$="[[_computeLoadingClass(_loading)]]"> <div id="loadedContent" class$="[[_computeLoadingClass(_loading)]]">
<div id="downloadContent" class$="[[_computeDownloadClass(_schemes)]]"> <div id="downloadContent" class$="[[_computeDownloadClass(_schemes)]]">
@ -61,7 +61,7 @@ limitations under the License.
<fieldset> <fieldset>
<gr-download-commands <gr-download-commands
id="downloadCommands" id="downloadCommands"
commands="[[_computeCommands(project, _schemesObj, _selectedScheme)]]" commands="[[_computeCommands(repo, _schemesObj, _selectedScheme)]]"
schemes="[[_schemes]]" schemes="[[_schemes]]"
selected-scheme="{{_selectedScheme}}"></gr-download-commands> selected-scheme="{{_selectedScheme}}"></gr-download-commands>
</fieldset> </fieldset>
@ -76,18 +76,18 @@ limitations under the License.
id="descriptionInput" id="descriptionInput"
class="description" class="description"
autocomplete="on" autocomplete="on"
placeholder="<Insert project description here>" placeholder="<Insert repo description here>"
bind-value="{{_projectConfig.description}}" bind-value="{{_repoConfig.description}}"
disabled$="[[_readOnly]]"></iron-autogrow-textarea> disabled$="[[_readOnly]]"></iron-autogrow-textarea>
</fieldset> </fieldset>
<h3 id="Options">Project Options</h3> <h3 id="Options">Repository Options</h3>
<fieldset id="options"> <fieldset id="options">
<section> <section>
<span class="title">State</span> <span class="title">State</span>
<span class="value"> <span class="value">
<gr-select <gr-select
id="stateSelect" id="stateSelect"
bind-value="{{_projectConfig.state}}"> bind-value="{{_repoConfig.state}}">
<select disabled$="[[_readOnly]]"> <select disabled$="[[_readOnly]]">
<template is="dom-repeat" items=[[_states]]> <template is="dom-repeat" items=[[_states]]>
<option value="[[item.value]]">[[item.label]]</option> <option value="[[item.value]]">[[item.label]]</option>
@ -101,7 +101,7 @@ limitations under the License.
<span class="value"> <span class="value">
<gr-select <gr-select
id="submitTypeSelect" id="submitTypeSelect"
bind-value="{{_projectConfig.submit_type}}"> bind-value="{{_repoConfig.submit_type}}">
<select disabled$="[[_readOnly]]"> <select disabled$="[[_readOnly]]">
<template is="dom-repeat" items="[[_submitTypes]]"> <template is="dom-repeat" items="[[_submitTypes]]">
<option value="[[item.value]]">[[item.label]]</option> <option value="[[item.value]]">[[item.label]]</option>
@ -115,10 +115,10 @@ limitations under the License.
<span class="value"> <span class="value">
<gr-select <gr-select
id="contentMergeSelect" id="contentMergeSelect"
bind-value="{{_projectConfig.use_content_merge.configured_value}}"> bind-value="{{_repoConfig.use_content_merge.configured_value}}">
<select disabled$="[[_readOnly]]"> <select disabled$="[[_readOnly]]">
<template is="dom-repeat" <template is="dom-repeat"
items="[[_formatBooleanSelect(_projectConfig.use_content_merge)]]"> items="[[_formatBooleanSelect(_repoConfig.use_content_merge)]]">
<option value="[[item.value]]">[[item.label]]</option> <option value="[[item.value]]">[[item.label]]</option>
</template> </template>
</select> </select>
@ -132,10 +132,10 @@ limitations under the License.
<span class="value"> <span class="value">
<gr-select <gr-select
id="newChangeSelect" id="newChangeSelect"
bind-value="{{_projectConfig.create_new_change_for_all_not_in_target.configured_value}}"> bind-value="{{_repoConfig.create_new_change_for_all_not_in_target.configured_value}}">
<select disabled$="[[_readOnly]]"> <select disabled$="[[_readOnly]]">
<template is="dom-repeat" <template is="dom-repeat"
items="[[_formatBooleanSelect(_projectConfig.create_new_change_for_all_not_in_target)]]"> items="[[_formatBooleanSelect(_repoConfig.create_new_change_for_all_not_in_target)]]">
<option value="[[item.value]]">[[item.label]]</option> <option value="[[item.value]]">[[item.label]]</option>
</template> </template>
</select> </select>
@ -147,10 +147,10 @@ limitations under the License.
<span class="value"> <span class="value">
<gr-select <gr-select
id="requireChangeIdSelect" id="requireChangeIdSelect"
bind-value="{{_projectConfig.require_change_id.configured_value}}"> bind-value="{{_repoConfig.require_change_id.configured_value}}">
<select disabled$="[[_readOnly]]"> <select disabled$="[[_readOnly]]">
<template is="dom-repeat" <template is="dom-repeat"
items="[[_formatBooleanSelect(_projectConfig.require_change_id)]]"> items="[[_formatBooleanSelect(_repoConfig.require_change_id)]]">
<option value="[[item.value]]">[[item.label]]</option> <option value="[[item.value]]">[[item.label]]</option>
</template> </template>
</select> </select>
@ -159,15 +159,15 @@ limitations under the License.
</section> </section>
<section <section
id="enableSignedPushSettings" id="enableSignedPushSettings"
class$="projectSettings [[_computeProjectsClass(_projectConfig.enable_signed_push)]]"> class$="repositorySettings [[_computeRepositoriesClass(_repoConfig.enable_signed_push)]]">
<span class="title">Enable signed push</span> <span class="title">Enable signed push</span>
<span class="value"> <span class="value">
<gr-select <gr-select
id="enableSignedPush" id="enableSignedPush"
bind-value="{{_projectConfig.enable_signed_push.configured_value}}"> bind-value="{{_repoConfig.enable_signed_push.configured_value}}">
<select disabled$="[[_readOnly]]"> <select disabled$="[[_readOnly]]">
<template is="dom-repeat" <template is="dom-repeat"
items="[[_formatBooleanSelect(_projectConfig.enable_signed_push)]]"> items="[[_formatBooleanSelect(_repoConfig.enable_signed_push)]]">
<option value="[[item.value]]">[[item.label]]</option> <option value="[[item.value]]">[[item.label]]</option>
</template> </template>
</select> </select>
@ -176,15 +176,15 @@ limitations under the License.
</section> </section>
<section <section
id="requireSignedPushSettings" id="requireSignedPushSettings"
class$="projectSettings [[_computeProjectsClass(_projectConfig.require_signed_push)]]"> class$="repositorySettings [[_computeRepositoriesClass(_repoConfig.require_signed_push)]]">
<span class="title">Require signed push</span> <span class="title">Require signed push</span>
<span class="value"> <span class="value">
<gr-select <gr-select
id="requireSignedPush" id="requireSignedPush"
bind-value="{{_projectConfig.require_signed_push.configured_value}}"> bind-value="{{_repoConfig.require_signed_push.configured_value}}">
<select disabled$="[[_readOnly]]"> <select disabled$="[[_readOnly]]">
<template is="dom-repeat" <template is="dom-repeat"
items="[[_formatBooleanSelect(_projectConfig.require_signed_push)]]"> items="[[_formatBooleanSelect(_repoConfig.require_signed_push)]]">
<option value="[[item.value]]">[[item.label]]</option> <option value="[[item.value]]">[[item.label]]</option>
</template> </template>
</select> </select>
@ -197,26 +197,26 @@ limitations under the License.
<span class="value"> <span class="value">
<gr-select <gr-select
id="rejectImplicitMergesSelect" id="rejectImplicitMergesSelect"
bind-value="{{_projectConfig.reject_implicit_merges.configured_value}}"> bind-value="{{_repoConfig.reject_implicit_merges.configured_value}}">
<select disabled$="[[_readOnly]]"> <select disabled$="[[_readOnly]]">
<template is="dom-repeat" <template is="dom-repeat"
items="[[_formatBooleanSelect(_projectConfig.reject_implicit_merges)]]"> items="[[_formatBooleanSelect(_repoConfig.reject_implicit_merges)]]">
<option value="[[item.value]]">[[item.label]]</option> <option value="[[item.value]]">[[item.label]]</option>
</template> </template>
</select> </select>
</gr-select> </gr-select>
</span> </span>
</section> </section>
<section id="noteDbSettings" class$="projectSettings [[_computeProjectsClass(_noteDbEnabled)]]"> <section id="noteDbSettings" class$="repositorySettings [[_computeRepositoriesClass(_noteDbEnabled)]]">
<span class="title"> <span class="title">
Enable adding unregistered users as reviewers and CCs on changes</span> Enable adding unregistered users as reviewers and CCs on changes</span>
<span class="value"> <span class="value">
<gr-select <gr-select
id="unRegisteredCcSelect" id="unRegisteredCcSelect"
bind-value="{{_projectConfig.enable_reviewer_by_email.configured_value}}"> bind-value="{{_repoConfig.enable_reviewer_by_email.configured_value}}">
<select disabled$="[[_readOnly]]"> <select disabled$="[[_readOnly]]">
<template is="dom-repeat" <template is="dom-repeat"
items="[[_formatBooleanSelect(_projectConfig.enable_reviewer_by_email)]]"> items="[[_formatBooleanSelect(_repoConfig.enable_reviewer_by_email)]]">
<option value="[[item.value]]">[[item.label]]</option> <option value="[[item.value]]">[[item.label]]</option>
</template> </template>
</select> </select>
@ -229,10 +229,10 @@ limitations under the License.
<span class="value"> <span class="value">
<gr-select <gr-select
id="setAllnewChangesPrivateByDefaultSelect" id="setAllnewChangesPrivateByDefaultSelect"
bind-value="{{_projectConfig.private_by_default.configured_value}}"> bind-value="{{_repoConfig.private_by_default.configured_value}}">
<select disabled$="[[_readOnly]]"> <select disabled$="[[_readOnly]]">
<template is="dom-repeat" <template is="dom-repeat"
items="[[_formatBooleanSelect(_projectConfig.private_by_default)]]"> items="[[_formatBooleanSelect(_repoConfig.private_by_default)]]">
<option value="[[item.value]]">[[item.label]]</option> <option value="[[item.value]]">[[item.label]]</option>
</template> </template>
</select> </select>
@ -244,7 +244,7 @@ limitations under the License.
<span class="value"> <span class="value">
<input <input
id="maxGitObjSizeInput" id="maxGitObjSizeInput"
bind-value="{{_projectConfig.max_object_size_limit.configured_value}}" bind-value="{{_repoConfig.max_object_size_limit.configured_value}}"
is="iron-input" is="iron-input"
type="text" type="text"
disabled$="[[_readOnly]]"> disabled$="[[_readOnly]]">
@ -255,10 +255,10 @@ limitations under the License.
<span class="value"> <span class="value">
<gr-select <gr-select
id="matchAuthoredDateWithCommitterDateSelect" id="matchAuthoredDateWithCommitterDateSelect"
bind-value="{{_projectConfig.match_author_to_committer_date.configured_value}}"> bind-value="{{_repoConfig.match_author_to_committer_date.configured_value}}">
<select disabled$="[[_readOnly]]"> <select disabled$="[[_readOnly]]">
<template is="dom-repeat" <template is="dom-repeat"
items="[[_formatBooleanSelect(_projectConfig.match_author_to_committer_date)]]"> items="[[_formatBooleanSelect(_repoConfig.match_author_to_committer_date)]]">
<option value="[[item.value]]">[[item.label]]</option> <option value="[[item.value]]">[[item.label]]</option>
</template> </template>
</select> </select>
@ -274,10 +274,10 @@ limitations under the License.
<span class="value"> <span class="value">
<gr-select <gr-select
id="contributorAgreementSelect" id="contributorAgreementSelect"
bind-value="{{_projectConfig.use_contributor_agreements.configured_value}}"> bind-value="{{_repoConfig.use_contributor_agreements.configured_value}}">
<select disabled$="[[_readOnly]]"> <select disabled$="[[_readOnly]]">
<template is="dom-repeat" <template is="dom-repeat"
items="[[_formatBooleanSelect(_projectConfig.use_contributor_agreements)]]"> items="[[_formatBooleanSelect(_repoConfig.use_contributor_agreements)]]">
<option value="[[item.value]]">[[item.label]]</option> <option value="[[item.value]]">[[item.label]]</option>
</template> </template>
</select> </select>
@ -289,10 +289,10 @@ limitations under the License.
<span class="value"> <span class="value">
<gr-select <gr-select
id="useSignedOffBySelect" id="useSignedOffBySelect"
bind-value="{{_projectConfig.use_signed_off_by.configured_value}}"> bind-value="{{_repoConfig.use_signed_off_by.configured_value}}">
<select disabled$="[[_readOnly]]"> <select disabled$="[[_readOnly]]">
<template is="dom-repeat" <template is="dom-repeat"
items="[[_formatBooleanSelect(_projectConfig.use_signed_off_by)]]"> items="[[_formatBooleanSelect(_repoConfig.use_signed_off_by)]]">
<option value="[[item.value]]">[[item.label]]</option> <option value="[[item.value]]">[[item.label]]</option>
</template> </template>
</select> </select>
@ -302,7 +302,7 @@ limitations under the License.
</fieldset> </fieldset>
<!-- TODO @beckysiegel add plugin config widgets --> <!-- TODO @beckysiegel add plugin config widgets -->
<gr-button <gr-button
on-tap="_handleSaveProjectConfig" on-tap="_handleSaveRepoConfig"
disabled$="[[_computeButtonDisabled(_readOnly, _configChanged)]]">Save changes</gr-button> disabled$="[[_computeButtonDisabled(_readOnly, _configChanged)]]">Save changes</gr-button>
</fieldset> </fieldset>
</div> </div>
@ -310,5 +310,5 @@ limitations under the License.
</main> </main>
<gr-rest-api-interface id="restAPI"></gr-rest-api-interface> <gr-rest-api-interface id="restAPI"></gr-rest-api-interface>
</template> </template>
<script src="gr-project.js"></script> <script src="gr-repo.js"></script>
</dom-module> </dom-module>

View File

@ -48,11 +48,11 @@
}; };
Polymer({ Polymer({
is: 'gr-project', is: 'gr-repo',
properties: { properties: {
params: Object, params: Object,
project: String, repo: String,
_configChanged: { _configChanged: {
type: Boolean, type: Boolean,
@ -68,7 +68,7 @@
observer: '_loggedInChanged', observer: '_loggedInChanged',
}, },
/** @type {?} */ /** @type {?} */
_projectConfig: Object, _repoConfig: Object,
_readOnly: { _readOnly: {
type: Boolean, type: Boolean,
value: true, value: true,
@ -104,35 +104,35 @@
}, },
observers: [ observers: [
'_handleConfigChanged(_projectConfig.*)', '_handleConfigChanged(_repoConfig.*)',
], ],
attached() { attached() {
this._loadProject(); this._loadRepo();
this.fire('title-change', {title: this.project}); this.fire('title-change', {title: this.repo});
}, },
_loadProject() { _loadRepo() {
if (!this.project) { return Promise.resolve(); } if (!this.repo) { return Promise.resolve(); }
const promises = []; const promises = [];
promises.push(this._getLoggedIn().then(loggedIn => { promises.push(this._getLoggedIn().then(loggedIn => {
this._loggedIn = loggedIn; this._loggedIn = loggedIn;
if (loggedIn) { if (loggedIn) {
this.$.restAPI.getProjectAccess(this.project).then(access => { this.$.restAPI.getRepoAccess(this.repo).then(access => {
// If the user is not an owner, is_owner is not a property. // If the user is not an owner, is_owner is not a property.
this._readOnly = !access[this.project].is_owner; this._readOnly = !access[this.repo].is_owner;
}); });
} }
})); }));
promises.push(this.$.restAPI.getProjectConfig(this.project).then( promises.push(this.$.restAPI.getProjectConfig(this.repo).then(
config => { config => {
if (!config.state) { if (!config.state) {
config.state = STATES.active.value; config.state = STATES.active.value;
} }
this._projectConfig = config; this._repoConfig = config;
this._loading = false; this._loading = false;
})); }));
@ -191,7 +191,7 @@
return this.$.restAPI.getLoggedIn(); return this.$.restAPI.getLoggedIn();
}, },
_formatProjectConfigForSave(p) { _formatRepoConfigForSave(p) {
const configInputObj = {}; const configInputObj = {};
for (const key in p) { for (const key in p) {
if (p.hasOwnProperty(key)) { if (p.hasOwnProperty(key)) {
@ -205,9 +205,9 @@
return configInputObj; return configInputObj;
}, },
_handleSaveProjectConfig() { _handleSaveRepoConfig() {
return this.$.restAPI.saveProjectConfig(this.project, return this.$.restAPI.saveRepoConfig(this.repo,
this._formatProjectConfigForSave(this._projectConfig)).then(() => { this._formatRepoConfigForSave(this._repoConfig)).then(() => {
this._configChanged = false; this._configChanged = false;
}); });
}, },
@ -236,7 +236,7 @@
} }
}, },
_computeCommands(project, schemesObj, _selectedScheme) { _computeCommands(repo, schemesObj, _selectedScheme) {
const commands = []; const commands = [];
let commandObj; let commandObj;
if (schemesObj.hasOwnProperty(_selectedScheme)) { if (schemesObj.hasOwnProperty(_selectedScheme)) {
@ -247,15 +247,15 @@
commands.push({ commands.push({
title, title,
command: commandObj[title] command: commandObj[title]
.replace('${project}', project) .replace('${project}', repo)
.replace('${project-base-name}', .replace('${project-base-name}',
project.substring(project.lastIndexOf('/') + 1)), repo.substring(repo.lastIndexOf('/') + 1)),
}); });
} }
return commands; return commands;
}, },
_computeProjectsClass(config) { _computeRepositoriesClass(config) {
return config ? 'showConfig': ''; return config ? 'showConfig': '';
}, },
}); });

View File

@ -16,26 +16,26 @@ limitations under the License.
--> -->
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes"> <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-project</title> <title>gr-repo</title>
<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script> <script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
<script src="../../../bower_components/web-component-tester/browser.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="../../../test/common-test-setup.html"/>
<link rel="import" href="gr-project.html"> <link rel="import" href="gr-repo.html">
<script>void(0);</script> <script>void(0);</script>
<test-fixture id="basic"> <test-fixture id="basic">
<template> <template>
<gr-project></gr-project> <gr-repo></gr-repo>
</template> </template>
</test-fixture> </test-fixture>
<script> <script>
suite('gr-project tests', () => { suite('gr-repo tests', () => {
let element; let element;
let sandbox; let sandbox;
const PROJECT = 'test-project'; const REPO = 'test-repo';
const SCHEMES = {http: {}, repo: {}, ssh: {}}; const SCHEMES = {http: {}, repo: {}, ssh: {}};
function getFormFields() { function getFormFields() {
@ -112,7 +112,7 @@ limitations under the License.
sandbox.restore(); sandbox.restore();
}); });
test('loading displays before project config is loaded', () => { test('loading displays before repo config is loaded', () => {
assert.isTrue(element.$.loading.classList.contains('loading')); assert.isTrue(element.$.loading.classList.contains('loading'));
assert.isFalse(getComputedStyle(element.$.loading).display === 'none'); assert.isFalse(getComputedStyle(element.$.loading).display === 'none');
assert.isTrue(element.$.loadedContent.classList.contains('loading')); assert.isTrue(element.$.loadedContent.classList.contains('loading'));
@ -140,30 +140,30 @@ limitations under the License.
}); });
test('form defaults to read only when not logged in', done => { test('form defaults to read only when not logged in', done => {
element.project = PROJECT; element.repo = REPO;
element._loadProject().then(() => { element._loadRepo().then(() => {
assert.isTrue(element._readOnly); assert.isTrue(element._readOnly);
done(); done();
}); });
}); });
test('form defaults to read only when logged in and not admin', done => { test('form defaults to read only when logged in and not admin', done => {
element.project = PROJECT; element.repo = REPO;
sandbox.stub(element, '_getLoggedIn', () => { sandbox.stub(element, '_getLoggedIn', () => {
return Promise.resolve(true); return Promise.resolve(true);
}); });
sandbox.stub(element.$.restAPI, 'getProjectAccess', () => { sandbox.stub(element.$.restAPI, 'getRepoAccess', () => {
return Promise.resolve({'test-project': {}}); return Promise.resolve({'test-repo': {}});
}); });
element._loadProject().then(() => { element._loadRepo().then(() => {
assert.isTrue(element._readOnly); assert.isTrue(element._readOnly);
done(); done();
}); });
}); });
test('all form elements are disabled when not admin', done => { test('all form elements are disabled when not admin', done => {
element.project = PROJECT; element.repo = REPO;
element._loadProject().then(() => { element._loadRepo().then(() => {
flushAsynchronousOperations(); flushAsynchronousOperations();
const formFields = getFormFields(); const formFields = getFormFields();
for (const field of formFields) { for (const field of formFields) {
@ -223,17 +223,17 @@ limitations under the License.
suite('admin', () => { suite('admin', () => {
setup(() => { setup(() => {
element.project = PROJECT; element.repo = REPO;
sandbox.stub(element, '_getLoggedIn', () => { sandbox.stub(element, '_getLoggedIn', () => {
return Promise.resolve(true); return Promise.resolve(true);
}); });
sandbox.stub(element.$.restAPI, 'getProjectAccess', () => { sandbox.stub(element.$.restAPI, 'getRepoAccess', () => {
return Promise.resolve({'test-project': {is_owner: true}}); return Promise.resolve({'test-repo': {is_owner: true}});
}); });
}); });
test('all form elements are enabled', done => { test('all form elements are enabled', done => {
element._loadProject().then(() => { element._loadRepo().then(() => {
flushAsynchronousOperations(); flushAsynchronousOperations();
const formFields = getFormFields(); const formFields = getFormFields();
for (const field of formFields) { for (const field of formFields) {
@ -245,8 +245,8 @@ limitations under the License.
}); });
test('state gets set correctly', done => { test('state gets set correctly', done => {
element._loadProject().then(() => { element._loadRepo().then(() => {
assert.equal(element._projectConfig.state, 'ACTIVE'); assert.equal(element._repoConfig.state, 'ACTIVE');
assert.equal(element.$.stateSelect.bindValue, 'ACTIVE'); assert.equal(element.$.stateSelect.bindValue, 'ACTIVE');
done(); done();
}); });
@ -257,12 +257,12 @@ limitations under the License.
element._noteDbEnabled = false; element._noteDbEnabled = false;
assert.equal( assert.equal(
element._computeProjectsClass(element._noteDbEnabled), ''); element._computeRepositoriesClass(element._noteDbEnabled), '');
element._noteDbEnabled = true; element._noteDbEnabled = true;
assert.equal( assert.equal(element._computeRepositoriesClass(
element._computeProjectsClass(element._noteDbEnabled), 'showConfig'); element._noteDbEnabled), 'showConfig');
const configInputObj = { const configInputObj = {
description: 'new description', description: 'new description',
@ -282,14 +282,14 @@ limitations under the License.
enable_reviewer_by_email: 'TRUE', enable_reviewer_by_email: 'TRUE',
}; };
const saveStub = sandbox.stub(element.$.restAPI, 'saveProjectConfig' const saveStub = sandbox.stub(element.$.restAPI, 'saveRepoConfig'
, () => { , () => {
return Promise.resolve({}); return Promise.resolve({});
}); });
const button = Polymer.dom(element.root).querySelector('gr-button'); const button = Polymer.dom(element.root).querySelector('gr-button');
element._loadProject().then(() => { element._loadRepo().then(() => {
assert.isTrue(button.hasAttribute('disabled')); assert.isTrue(button.hasAttribute('disabled'));
assert.isFalse(element.$.Title.classList.contains('edited')); assert.isFalse(element.$.Title.classList.contains('edited'));
element.$.descriptionInput.bindValue = configInputObj.description; element.$.descriptionInput.bindValue = configInputObj.description;
@ -324,13 +324,13 @@ limitations under the License.
assert.isTrue(element.$.configurations.classList.contains('edited')); assert.isTrue(element.$.configurations.classList.contains('edited'));
const formattedObj = const formattedObj =
element._formatProjectConfigForSave(element._projectConfig); element._formatRepoConfigForSave(element._repoConfig);
assert.deepEqual(formattedObj, configInputObj); assert.deepEqual(formattedObj, configInputObj);
element._handleSaveProjectConfig().then(() => { element._handleSaveRepoConfig().then(() => {
assert.isTrue(button.hasAttribute('disabled')); assert.isTrue(button.hasAttribute('disabled'));
assert.isFalse(element.$.Title.classList.contains('edited')); assert.isFalse(element.$.Title.classList.contains('edited'));
assert.isTrue(saveStub.lastCall.calledWithExactly(PROJECT, assert.isTrue(saveStub.lastCall.calledWithExactly(REPO,
configInputObj)); configInputObj));
done(); done();
}); });

View File

@ -77,7 +77,7 @@
if (input.startsWith('refs/heads/')) { if (input.startsWith('refs/heads/')) {
input = input.substring('refs/heads/'.length); input = input.substring('refs/heads/'.length);
} }
return this.$.restAPI.getProjectBranches( return this.$.restAPI.getRepoBranches(
input, this.project, SUGGESTIONS_LIMIT).then(response => { input, this.project, SUGGESTIONS_LIMIT).then(response => {
const branches = []; const branches = [];
let branch; let branch;

View File

@ -39,7 +39,7 @@ limitations under the License.
setup(() => { setup(() => {
sandbox = sinon.sandbox.create(); sandbox = sinon.sandbox.create();
stub('gr-rest-api-interface', { stub('gr-rest-api-interface', {
getProjectBranches(input) { getRepoBranches(input) {
if (input.startsWith('test')) { if (input.startsWith('test')) {
return Promise.resolve([ return Promise.resolve([
{ {

View File

@ -57,7 +57,7 @@
if (input.startsWith('refs/heads/')) { if (input.startsWith('refs/heads/')) {
input = input.substring('refs/heads/'.length); input = input.substring('refs/heads/'.length);
} }
return this.$.restAPI.getProjectBranches( return this.$.restAPI.getRepoBranches(
input, this.project, SUGGESTIONS_LIMIT).then(response => { input, this.project, SUGGESTIONS_LIMIT).then(response => {
const branches = []; const branches = [];
let branch; let branch;

View File

@ -37,7 +37,7 @@ limitations under the License.
setup(() => { setup(() => {
stub('gr-rest-api-interface', { stub('gr-rest-api-interface', {
getProjectBranches(input) { getRepoBranches(input) {
if (input.startsWith('test')) { if (input.startsWith('test')) {
return Promise.resolve([ return Promise.resolve([
{ {

View File

@ -164,7 +164,7 @@ limitations under the License.
<li> <li>
<a <a
class="browse linksTitle" class="browse linksTitle"
href$="[[_computeRelativeURL('/admin/projects')]]"> href$="[[_computeRelativeURL('/admin/repos')]]">
Browse</a> Browse</a>
</li> </li>
</ul> </ul>

View File

@ -55,31 +55,33 @@
// Matches /admin/create-project // Matches /admin/create-project
LEGACY_CREATE_GROUP: /^\/admin\/create-group\/?$/, LEGACY_CREATE_GROUP: /^\/admin\/create-group\/?$/,
// Matches /admin/projects/<project> PROJECT_OLD: /^\/admin\/(projects)\/?(.+)?$/,
PROJECT: /^\/admin\/projects\/([^,]+)$/,
// Matches /admin/projects/<project>,commands. // Matches /admin/repos/<repo>
PROJECT_COMMANDS: /^\/admin\/projects\/(.+),commands$/, REPO: /^\/admin\/repos\/([^,]+)$/,
// Matches /admin/projects/<project>,access. // Matches /admin/repos/<repo>,commands.
PROJECT_ACCESS: /^\/admin\/projects\/(.+),access$/, REPO_COMMANDS: /^\/admin\/repos\/(.+),commands$/,
// Matches /admin/projects[,<offset>][/]. // Matches /admin/repos/<repos>,access.
PROJECT_LIST_OFFSET: /^\/admin\/projects(,(\d+))?(\/)?$/, REPO_ACCESS: /^\/admin\/repos\/(.+),access$/,
PROJECT_LIST_FILTER: '/admin/projects/q/filter::filter',
PROJECT_LIST_FILTER_OFFSET: '/admin/projects/q/filter::filter,:offset',
// Matches /admin/projects/<project>,branches[,<offset>]. // Matches /admin/repos[,<offset>][/].
BRANCH_LIST_OFFSET: /^\/admin\/projects\/(.+),branches(,(.+))?$/, REPO_LIST_OFFSET: /^\/admin\/repos(,(\d+))?(\/)?$/,
BRANCH_LIST_FILTER: '/admin/projects/:project,branches/q/filter::filter', REPO_LIST_FILTER: '/admin/repos/q/filter::filter',
REPO_LIST_FILTER_OFFSET: '/admin/repos/q/filter::filter,:offset',
// Matches /admin/repos/<repo>,branches[,<offset>].
BRANCH_LIST_OFFSET: /^\/admin\/repos\/(.+),branches(,(.+))?$/,
BRANCH_LIST_FILTER: '/admin/repos/:repo,branches/q/filter::filter',
BRANCH_LIST_FILTER_OFFSET: BRANCH_LIST_FILTER_OFFSET:
'/admin/projects/:project,branches/q/filter::filter,:offset', '/admin/repos/:repo,branches/q/filter::filter,:offset',
// Matches /admin/projects/<project>,tags[,<offset>]. // Matches /admin/repos/<repo>,tags[,<offset>].
TAG_LIST_OFFSET: /^\/admin\/projects\/(.+),tags(,(.+))?$/, TAG_LIST_OFFSET: /^\/admin\/repos\/(.+),tags(,(.+))?$/,
TAG_LIST_FILTER: '/admin/projects/:project,tags/q/filter::filter', TAG_LIST_FILTER: '/admin/repos/:repo,tags/q/filter::filter',
TAG_LIST_FILTER_OFFSET: TAG_LIST_FILTER_OFFSET:
'/admin/projects/:project,tags/q/filter::filter,:offset', '/admin/repos/:repo,tags/q/filter::filter,:offset',
PLUGINS: /^\/plugins\/(.+)$/, PLUGINS: /^\/plugins\/(.+)$/,
@ -662,11 +664,14 @@
this._mapRoute(RoutePattern.GROUP, '_handleGroupRoute', true); this._mapRoute(RoutePattern.GROUP, '_handleGroupRoute', true);
this._mapRoute(RoutePattern.PROJECT_COMMANDS, this._mapRoute(RoutePattern.PROJECT_OLD,
'_handleProjectCommandsRoute', true); '_handleProjectsOldRoute');
this._mapRoute(RoutePattern.PROJECT_ACCESS, this._mapRoute(RoutePattern.REPO_COMMANDS,
'_handleProjectAccessRoute'); '_handleRepoCommandsRoute', true);
this._mapRoute(RoutePattern.REPO_ACCESS,
'_handleRepoAccessRoute');
this._mapRoute(RoutePattern.BRANCH_LIST_OFFSET, this._mapRoute(RoutePattern.BRANCH_LIST_OFFSET,
'_handleBranchListOffsetRoute'); '_handleBranchListOffsetRoute');
@ -692,16 +697,16 @@
this._mapRoute(RoutePattern.LEGACY_CREATE_PROJECT, this._mapRoute(RoutePattern.LEGACY_CREATE_PROJECT,
'_handleCreateProjectRoute', true); '_handleCreateProjectRoute', true);
this._mapRoute(RoutePattern.PROJECT_LIST_OFFSET, this._mapRoute(RoutePattern.REPO_LIST_OFFSET,
'_handleProjectListOffsetRoute'); '_handleRepoListOffsetRoute');
this._mapRoute(RoutePattern.PROJECT_LIST_FILTER_OFFSET, this._mapRoute(RoutePattern.REPO_LIST_FILTER_OFFSET,
'_handleProjectListFilterOffsetRoute'); '_handleRepoListFilterOffsetRoute');
this._mapRoute(RoutePattern.PROJECT_LIST_FILTER, this._mapRoute(RoutePattern.REPO_LIST_FILTER,
'_handleProjectListFilterRoute'); '_handleRepoListFilterRoute');
this._mapRoute(RoutePattern.PROJECT, '_handleProjectRoute'); this._mapRoute(RoutePattern.REPO, '_handleRepoRoute');
this._mapRoute(RoutePattern.PLUGINS, '_handlePassThroughRoute'); this._mapRoute(RoutePattern.PLUGINS, '_handlePassThroughRoute');
@ -967,30 +972,38 @@
}); });
}, },
_handleProjectCommandsRoute(data) { _handleProjectsOldRoute(data) {
if (data.params[1]) {
this._redirect('/admin/repos/' + encodeURIComponent(data.params[1]));
} else {
this._redirect('/admin/repos');
}
},
_handleRepoCommandsRoute(data) {
this._setParams({ this._setParams({
view: Gerrit.Nav.View.ADMIN, view: Gerrit.Nav.View.ADMIN,
adminView: 'gr-project-commands', adminView: 'gr-repo-commands',
detailType: 'commands', detailType: 'commands',
project: data.params[0], repo: data.params[0],
}); });
}, },
_handleProjectAccessRoute(data) { _handleRepoAccessRoute(data) {
this._setParams({ this._setParams({
view: Gerrit.Nav.View.ADMIN, view: Gerrit.Nav.View.ADMIN,
adminView: 'gr-project-access', adminView: 'gr-repo-access',
detailType: 'access', detailType: 'access',
project: data.params[0], repo: data.params[0],
}); });
}, },
_handleBranchListOffsetRoute(data) { _handleBranchListOffsetRoute(data) {
this._setParams({ this._setParams({
view: Gerrit.Nav.View.ADMIN, view: Gerrit.Nav.View.ADMIN,
adminView: 'gr-project-detail-list', adminView: 'gr-repo-detail-list',
detailType: 'branches', detailType: 'branches',
project: data.params[0], repo: data.params[0],
offset: data.params[2] || 0, offset: data.params[2] || 0,
filter: null, filter: null,
}); });
@ -999,9 +1012,9 @@
_handleBranchListFilterOffsetRoute(data) { _handleBranchListFilterOffsetRoute(data) {
this._setParams({ this._setParams({
view: Gerrit.Nav.View.ADMIN, view: Gerrit.Nav.View.ADMIN,
adminView: 'gr-project-detail-list', adminView: 'gr-repo-detail-list',
detailType: 'branches', detailType: 'branches',
project: data.params.project, repo: data.params.repo,
offset: data.params.offset, offset: data.params.offset,
filter: data.params.filter, filter: data.params.filter,
}); });
@ -1010,9 +1023,9 @@
_handleBranchListFilterRoute(data) { _handleBranchListFilterRoute(data) {
this._setParams({ this._setParams({
view: Gerrit.Nav.View.ADMIN, view: Gerrit.Nav.View.ADMIN,
adminView: 'gr-project-detail-list', adminView: 'gr-repo-detail-list',
detailType: 'branches', detailType: 'branches',
project: data.params.project, repo: data.params.repo,
filter: data.params.filter || null, filter: data.params.filter || null,
}); });
}, },
@ -1020,9 +1033,9 @@
_handleTagListOffsetRoute(data) { _handleTagListOffsetRoute(data) {
this._setParams({ this._setParams({
view: Gerrit.Nav.View.ADMIN, view: Gerrit.Nav.View.ADMIN,
adminView: 'gr-project-detail-list', adminView: 'gr-repo-detail-list',
detailType: 'tags', detailType: 'tags',
project: data.params[0], repo: data.params[0],
offset: data.params[2] || 0, offset: data.params[2] || 0,
filter: null, filter: null,
}); });
@ -1031,9 +1044,9 @@
_handleTagListFilterOffsetRoute(data) { _handleTagListFilterOffsetRoute(data) {
this._setParams({ this._setParams({
view: Gerrit.Nav.View.ADMIN, view: Gerrit.Nav.View.ADMIN,
adminView: 'gr-project-detail-list', adminView: 'gr-repo-detail-list',
detailType: 'tags', detailType: 'tags',
project: data.params.project, repo: data.params.repo,
offset: data.params.offset, offset: data.params.offset,
filter: data.params.filter, filter: data.params.filter,
}); });
@ -1042,36 +1055,36 @@
_handleTagListFilterRoute(data) { _handleTagListFilterRoute(data) {
this._setParams({ this._setParams({
view: Gerrit.Nav.View.ADMIN, view: Gerrit.Nav.View.ADMIN,
adminView: 'gr-project-detail-list', adminView: 'gr-repo-detail-list',
detailType: 'tags', detailType: 'tags',
project: data.params.project, repo: data.params.repo,
filter: data.params.filter || null, filter: data.params.filter || null,
}); });
}, },
_handleProjectListOffsetRoute(data) { _handleRepoListOffsetRoute(data) {
this._setParams({ this._setParams({
view: Gerrit.Nav.View.ADMIN, view: Gerrit.Nav.View.ADMIN,
adminView: 'gr-project-list', adminView: 'gr-repo-list',
offset: data.params[1] || 0, offset: data.params[1] || 0,
filter: null, filter: null,
openCreateModal: data.hash === 'create', openCreateModal: data.hash === 'create',
}); });
}, },
_handleProjectListFilterOffsetRoute(data) { _handleRepoListFilterOffsetRoute(data) {
this._setParams({ this._setParams({
view: Gerrit.Nav.View.ADMIN, view: Gerrit.Nav.View.ADMIN,
adminView: 'gr-project-list', adminView: 'gr-repo-list',
offset: data.params.offset, offset: data.params.offset,
filter: data.params.filter, filter: data.params.filter,
}); });
}, },
_handleProjectListFilterRoute(data) { _handleRepoListFilterRoute(data) {
this._setParams({ this._setParams({
view: Gerrit.Nav.View.ADMIN, view: Gerrit.Nav.View.ADMIN,
adminView: 'gr-project-list', adminView: 'gr-repo-list',
filter: data.params.filter || null, filter: data.params.filter || null,
}); });
}, },
@ -1088,11 +1101,11 @@
this._redirect('/admin/groups#create'); this._redirect('/admin/groups#create');
}, },
_handleProjectRoute(data) { _handleRepoRoute(data) {
this._setParams({ this._setParams({
view: Gerrit.Nav.View.ADMIN, view: Gerrit.Nav.View.ADMIN,
project: data.params[0], repo: data.params[0],
adminView: 'gr-project', adminView: 'gr-repo',
}); });
}, },

View File

@ -138,7 +138,7 @@ limitations under the License.
'_handlePluginListFilterRoute', '_handlePluginListFilterRoute',
'_handlePluginListOffsetRoute', '_handlePluginListOffsetRoute',
'_handlePluginListRoute', '_handlePluginListRoute',
'_handleProjectCommandsRoute', '_handleRepoCommandsRoute',
'_handleSettingsLegacyRoute', '_handleSettingsLegacyRoute',
'_handleSettingsRoute', '_handleSettingsRoute',
]; ];
@ -156,12 +156,13 @@ limitations under the License.
'_handleLegacyLinenum', '_handleLegacyLinenum',
'_handleImproperlyEncodedPlusRoute', '_handleImproperlyEncodedPlusRoute',
'_handlePassThroughRoute', '_handlePassThroughRoute',
'_handleProjectAccessRoute',
'_handleProjectDashboardRoute', '_handleProjectDashboardRoute',
'_handleProjectListFilterOffsetRoute', '_handleProjectsOldRoute',
'_handleProjectListFilterRoute', '_handleRepoAccessRoute',
'_handleProjectListOffsetRoute', '_handleRepoListFilterOffsetRoute',
'_handleProjectRoute', '_handleRepoListFilterRoute',
'_handleRepoListOffsetRoute',
'_handleRepoRoute',
'_handleQueryLegacySuffixRoute', '_handleQueryLegacySuffixRoute',
'_handleQueryRoute', '_handleQueryRoute',
'_handleRegisterRoute', '_handleRegisterRoute',
@ -921,33 +922,33 @@ limitations under the License.
}); });
}); });
suite('project routes', () => { suite('repo routes', () => {
test('_handleProjectRoute', () => { test('_handleRepoRoute', () => {
const data = {params: {0: 4321}}; const data = {params: {0: 4321}};
assertDataToParams(data, '_handleProjectRoute', { assertDataToParams(data, '_handleRepoRoute', {
view: Gerrit.Nav.View.ADMIN, view: Gerrit.Nav.View.ADMIN,
adminView: 'gr-project', adminView: 'gr-repo',
project: 4321, repo: 4321,
}); });
}); });
test('_handleProjectCommandsRoute', () => { test('_handleRepoCommandsRoute', () => {
const data = {params: {0: 4321}}; const data = {params: {0: 4321}};
assertDataToParams(data, '_handleProjectCommandsRoute', { assertDataToParams(data, '_handleRepoCommandsRoute', {
view: Gerrit.Nav.View.ADMIN, view: Gerrit.Nav.View.ADMIN,
adminView: 'gr-project-commands', adminView: 'gr-repo-commands',
detailType: 'commands', detailType: 'commands',
project: 4321, repo: 4321,
}); });
}); });
test('_handleProjectAccessRoute', () => { test('_handleRepoAccessRoute', () => {
const data = {params: {0: 4321}}; const data = {params: {0: 4321}};
assertDataToParams(data, '_handleProjectAccessRoute', { assertDataToParams(data, '_handleRepoAccessRoute', {
view: Gerrit.Nav.View.ADMIN, view: Gerrit.Nav.View.ADMIN,
adminView: 'gr-project-access', adminView: 'gr-repo-access',
detailType: 'access', detailType: 'access',
project: 4321, repo: 4321,
}); });
}); });
@ -956,9 +957,9 @@ limitations under the License.
const data = {params: {0: 4321}}; const data = {params: {0: 4321}};
assertDataToParams(data, '_handleBranchListOffsetRoute', { assertDataToParams(data, '_handleBranchListOffsetRoute', {
view: Gerrit.Nav.View.ADMIN, view: Gerrit.Nav.View.ADMIN,
adminView: 'gr-project-detail-list', adminView: 'gr-repo-detail-list',
detailType: 'branches', detailType: 'branches',
project: 4321, repo: 4321,
offset: 0, offset: 0,
filter: null, filter: null,
}); });
@ -966,33 +967,33 @@ limitations under the License.
data.params[2] = 42; data.params[2] = 42;
assertDataToParams(data, '_handleBranchListOffsetRoute', { assertDataToParams(data, '_handleBranchListOffsetRoute', {
view: Gerrit.Nav.View.ADMIN, view: Gerrit.Nav.View.ADMIN,
adminView: 'gr-project-detail-list', adminView: 'gr-repo-detail-list',
detailType: 'branches', detailType: 'branches',
project: 4321, repo: 4321,
offset: 42, offset: 42,
filter: null, filter: null,
}); });
}); });
test('_handleBranchListFilterOffsetRoute', () => { test('_handleBranchListFilterOffsetRoute', () => {
const data = {params: {project: 4321, filter: 'foo', offset: 42}}; const data = {params: {repo: 4321, filter: 'foo', offset: 42}};
assertDataToParams(data, '_handleBranchListFilterOffsetRoute', { assertDataToParams(data, '_handleBranchListFilterOffsetRoute', {
view: Gerrit.Nav.View.ADMIN, view: Gerrit.Nav.View.ADMIN,
adminView: 'gr-project-detail-list', adminView: 'gr-repo-detail-list',
detailType: 'branches', detailType: 'branches',
project: 4321, repo: 4321,
offset: 42, offset: 42,
filter: 'foo', filter: 'foo',
}); });
}); });
test('_handleBranchListFilterRoute', () => { test('_handleBranchListFilterRoute', () => {
const data = {params: {project: 4321, filter: 'foo'}}; const data = {params: {repo: 4321, filter: 'foo'}};
assertDataToParams(data, '_handleBranchListFilterRoute', { assertDataToParams(data, '_handleBranchListFilterRoute', {
view: Gerrit.Nav.View.ADMIN, view: Gerrit.Nav.View.ADMIN,
adminView: 'gr-project-detail-list', adminView: 'gr-repo-detail-list',
detailType: 'branches', detailType: 'branches',
project: 4321, repo: 4321,
filter: 'foo', filter: 'foo',
}); });
}); });
@ -1003,99 +1004,99 @@ limitations under the License.
const data = {params: {0: 4321}}; const data = {params: {0: 4321}};
assertDataToParams(data, '_handleTagListOffsetRoute', { assertDataToParams(data, '_handleTagListOffsetRoute', {
view: Gerrit.Nav.View.ADMIN, view: Gerrit.Nav.View.ADMIN,
adminView: 'gr-project-detail-list', adminView: 'gr-repo-detail-list',
detailType: 'tags', detailType: 'tags',
project: 4321, repo: 4321,
offset: 0, offset: 0,
filter: null, filter: null,
}); });
}); });
test('_handleTagListFilterOffsetRoute', () => { test('_handleTagListFilterOffsetRoute', () => {
const data = {params: {project: 4321, filter: 'foo', offset: 42}}; const data = {params: {repo: 4321, filter: 'foo', offset: 42}};
assertDataToParams(data, '_handleTagListFilterOffsetRoute', { assertDataToParams(data, '_handleTagListFilterOffsetRoute', {
view: Gerrit.Nav.View.ADMIN, view: Gerrit.Nav.View.ADMIN,
adminView: 'gr-project-detail-list', adminView: 'gr-repo-detail-list',
detailType: 'tags', detailType: 'tags',
project: 4321, repo: 4321,
offset: 42, offset: 42,
filter: 'foo', filter: 'foo',
}); });
}); });
test('_handleTagListFilterRoute', () => { test('_handleTagListFilterRoute', () => {
const data = {params: {project: 4321}}; const data = {params: {repo: 4321}};
assertDataToParams(data, '_handleTagListFilterRoute', { assertDataToParams(data, '_handleTagListFilterRoute', {
view: Gerrit.Nav.View.ADMIN, view: Gerrit.Nav.View.ADMIN,
adminView: 'gr-project-detail-list', adminView: 'gr-repo-detail-list',
detailType: 'tags', detailType: 'tags',
project: 4321, repo: 4321,
filter: null, filter: null,
}); });
data.params.filter = 'foo'; data.params.filter = 'foo';
assertDataToParams(data, '_handleTagListFilterRoute', { assertDataToParams(data, '_handleTagListFilterRoute', {
view: Gerrit.Nav.View.ADMIN, view: Gerrit.Nav.View.ADMIN,
adminView: 'gr-project-detail-list', adminView: 'gr-repo-detail-list',
detailType: 'tags', detailType: 'tags',
project: 4321, repo: 4321,
filter: 'foo', filter: 'foo',
}); });
}); });
}); });
suite('project list routes', () => { suite('repo list routes', () => {
test('_handleProjectListOffsetRoute', () => { test('_handleRepoListOffsetRoute', () => {
const data = {params: {}}; const data = {params: {}};
assertDataToParams(data, '_handleProjectListOffsetRoute', { assertDataToParams(data, '_handleRepoListOffsetRoute', {
view: Gerrit.Nav.View.ADMIN, view: Gerrit.Nav.View.ADMIN,
adminView: 'gr-project-list', adminView: 'gr-repo-list',
offset: 0, offset: 0,
filter: null, filter: null,
openCreateModal: false, openCreateModal: false,
}); });
data.params[1] = 42; data.params[1] = 42;
assertDataToParams(data, '_handleProjectListOffsetRoute', { assertDataToParams(data, '_handleRepoListOffsetRoute', {
view: Gerrit.Nav.View.ADMIN, view: Gerrit.Nav.View.ADMIN,
adminView: 'gr-project-list', adminView: 'gr-repo-list',
offset: 42, offset: 42,
filter: null, filter: null,
openCreateModal: false, openCreateModal: false,
}); });
data.hash = 'create'; data.hash = 'create';
assertDataToParams(data, '_handleProjectListOffsetRoute', { assertDataToParams(data, '_handleRepoListOffsetRoute', {
view: Gerrit.Nav.View.ADMIN, view: Gerrit.Nav.View.ADMIN,
adminView: 'gr-project-list', adminView: 'gr-repo-list',
offset: 42, offset: 42,
filter: null, filter: null,
openCreateModal: true, openCreateModal: true,
}); });
}); });
test('_handleProjectListFilterOffsetRoute', () => { test('_handleRepoListFilterOffsetRoute', () => {
const data = {params: {filter: 'foo', offset: 42}}; const data = {params: {filter: 'foo', offset: 42}};
assertDataToParams(data, '_handleProjectListFilterOffsetRoute', { assertDataToParams(data, '_handleRepoListFilterOffsetRoute', {
view: Gerrit.Nav.View.ADMIN, view: Gerrit.Nav.View.ADMIN,
adminView: 'gr-project-list', adminView: 'gr-repo-list',
offset: 42, offset: 42,
filter: 'foo', filter: 'foo',
}); });
}); });
test('_handleProjectListFilterRoute', () => { test('_handleRepoListFilterRoute', () => {
const data = {params: {}}; const data = {params: {}};
assertDataToParams(data, '_handleProjectListFilterRoute', { assertDataToParams(data, '_handleRepoListFilterRoute', {
view: Gerrit.Nav.View.ADMIN, view: Gerrit.Nav.View.ADMIN,
adminView: 'gr-project-list', adminView: 'gr-repo-list',
filter: null, filter: null,
}); });
data.params.filter = 'foo'; data.params.filter = 'foo';
assertDataToParams(data, '_handleProjectListFilterRoute', { assertDataToParams(data, '_handleRepoListFilterRoute', {
view: Gerrit.Nav.View.ADMIN, view: Gerrit.Nav.View.ADMIN,
adminView: 'gr-project-list', adminView: 'gr-repo-list',
filter: 'foo', filter: 'foo',
}); });
}); });

View File

@ -14,19 +14,19 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
--> -->
<link rel="import" href="../../../bower_components/polymer/polymer.html"> <link rel="import" href="../../../bower_components/polymer/polymer.html">
<link rel="import" href="../../admin/gr-project-command/gr-project-command.html"> <link rel="import" href="../../admin/gr-repo-command/gr-repo-command.html">
<dom-module id="gr-plugin-project-command"> <dom-module id="gr-plugin-repo-command">
<template> <template>
<gr-project-command title="[[title]]"> <gr-repo-command title="[[title]]">
</gr-project-command> </gr-repo-command>
</template> </template>
<script> <script>
Polymer({ Polymer({
is: 'gr-plugin-project-command', is: 'gr-plugin-repo-command',
properties: { properties: {
title: String, title: String,
projectName: String, repoName: String,
config: Object, config: Object,
}, },
}); });

View File

@ -16,8 +16,8 @@ limitations under the License.
<link rel="import" href="../../../bower_components/polymer/polymer.html"> <link rel="import" href="../../../bower_components/polymer/polymer.html">
<link rel="import" href="../../shared/gr-js-api-interface/gr-js-api-interface.html"> <link rel="import" href="../../shared/gr-js-api-interface/gr-js-api-interface.html">
<link rel="import" href="gr-plugin-project-command.html"> <link rel="import" href="gr-plugin-repo-command.html">
<dom-module id="gr-project-api"> <dom-module id="gr-repo-api">
<script src="gr-project-api.js"></script> <script src="gr-repo-api.js"></script>
</dom-module> </dom-module>

View File

@ -15,37 +15,37 @@
'use strict'; 'use strict';
// Prevent redefinition. // Prevent redefinition.
if (window.GrProjectApi) { return; } if (window.GrRepoApi) { return; }
function GrProjectApi(plugin) { function GrRepoApi(plugin) {
this._hook = null; this._hook = null;
this.plugin = plugin; this.plugin = plugin;
} }
GrProjectApi.prototype._createHook = function(title) { GrRepoApi.prototype._createHook = function(title) {
this._hook = this.plugin.hook('project-command').onAttached(element => { this._hook = this.plugin.hook('repo-command').onAttached(element => {
const pluginCommand = const pluginCommand =
document.createElement('gr-plugin-project-command'); document.createElement('gr-plugin-repo-command');
pluginCommand.title = title; pluginCommand.title = title;
element.appendChild(pluginCommand); element.appendChild(pluginCommand);
}); });
}; };
GrProjectApi.prototype.createCommand = function(title, callback) { GrRepoApi.prototype.createCommand = function(title, callback) {
if (this._hook) { if (this._hook) {
console.warn('Already set up.'); console.warn('Already set up.');
return this._hook; return this._hook;
} }
this._createHook(title); this._createHook(title);
this._hook.onAttached(element => { this._hook.onAttached(element => {
if (callback(element.projectName, element.config) === false) { if (callback(element.repoName, element.config) === false) {
element.hidden = true; element.hidden = true;
} }
}); });
return this; return this;
}; };
GrProjectApi.prototype.onTap = function(callback) { GrRepoApi.prototype.onTap = function(callback) {
if (!this._hook) { if (!this._hook) {
console.warn('Call createCommand first.'); console.warn('Call createCommand first.');
return this; return this;
@ -56,5 +56,5 @@
return this; return this;
}; };
window.GrProjectApi = GrProjectApi; window.GrRepoApi = GrRepoApi;
})(window); })(window);

View File

@ -16,27 +16,27 @@ limitations under the License.
--> -->
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes"> <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-project-api</title> <title>gr-repo-api</title>
<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script> <script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
<script src="../../../bower_components/web-component-tester/browser.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="../../../test/common-test-setup.html"/>
<link rel="import" href="../gr-endpoint-decorator/gr-endpoint-decorator.html"> <link rel="import" href="../gr-endpoint-decorator/gr-endpoint-decorator.html">
<link rel="import" href="gr-project-api.html"> <link rel="import" href="gr-repo-api.html">
<script>void(0);</script> <script>void(0);</script>
<test-fixture id="basic"> <test-fixture id="basic">
<template> <template>
<gr-endpoint-decorator name="project-command"> <gr-endpoint-decorator name="repo-command">
</gr-endpoint-decorator> </gr-endpoint-decorator>
</template> </template>
</test-fixture> </test-fixture>
<script> <script>
suite('gr-project-api tests', () => { suite('gr-repo-api tests', () => {
let sandbox; let sandbox;
let projectApi; let repoApi;
setup(() => { setup(() => {
sandbox = sinon.sandbox.create(); sandbox = sinon.sandbox.create();
@ -44,30 +44,30 @@ limitations under the License.
Gerrit.install(p => { plugin = p; }, '0.1', Gerrit.install(p => { plugin = p; }, '0.1',
'http://test.com/plugins/testplugin/static/test.js'); 'http://test.com/plugins/testplugin/static/test.js');
sandbox.stub(Gerrit, '_arePluginsLoaded').returns(true); sandbox.stub(Gerrit, '_arePluginsLoaded').returns(true);
projectApi = plugin.project(); repoApi = plugin.project();
}); });
teardown(() => { teardown(() => {
projectApi = null; repoApi = null;
sandbox.restore(); sandbox.restore();
}); });
test('exists', () => { test('exists', () => {
assert.isOk(projectApi); assert.isOk(repoApi);
}); });
test('works', done => { test('works', done => {
const attachedStub = sandbox.stub(); const attachedStub = sandbox.stub();
const tapStub = sandbox.stub(); const tapStub = sandbox.stub();
projectApi repoApi
.createCommand('foo', attachedStub) .createCommand('foo', attachedStub)
.onTap(tapStub); .onTap(tapStub);
const element = fixture('basic'); const element = fixture('basic');
flush(() => { flush(() => {
assert.isTrue(attachedStub.called); assert.isTrue(attachedStub.called);
const pluginCommand = element.$$('gr-plugin-project-command'); const pluginCommand = element.$$('gr-plugin-repo-command');
assert.isOk(pluginCommand); assert.isOk(pluginCommand);
const command = pluginCommand.$$('gr-project-command'); const command = pluginCommand.$$('gr-repo-command');
assert.isOk(command); assert.isOk(command);
assert.equal(command.title, 'foo'); assert.equal(command.title, 'foo');
assert.isFalse(tapStub.called); assert.isFalse(tapStub.called);

View File

@ -21,7 +21,7 @@ limitations under the License.
<link rel="import" href="../../plugins/gr-dom-hooks/gr-dom-hooks.html"> <link rel="import" href="../../plugins/gr-dom-hooks/gr-dom-hooks.html">
<link rel="import" href="../../plugins/gr-event-helper/gr-event-helper.html"> <link rel="import" href="../../plugins/gr-event-helper/gr-event-helper.html">
<link rel="import" href="../../plugins/gr-popup-interface/gr-popup-interface.html"> <link rel="import" href="../../plugins/gr-popup-interface/gr-popup-interface.html">
<link rel="import" href="../../plugins/gr-project-api/gr-project-api.html"> <link rel="import" href="../../plugins/gr-repo-api/gr-repo-api.html">
<link rel="import" href="../../plugins/gr-theme-api/gr-theme-api.html"> <link rel="import" href="../../plugins/gr-theme-api/gr-theme-api.html">
<link rel="import" href="../gr-rest-api-interface/gr-rest-api-interface.html"> <link rel="import" href="../gr-rest-api-interface/gr-rest-api-interface.html">

View File

@ -207,7 +207,7 @@
}; };
Plugin.prototype.project = function() { Plugin.prototype.project = function() {
return new GrProjectApi(this); return new GrRepoApi(this);
}; };
/** /**

View File

@ -234,32 +234,40 @@
return this._fetchSharedCacheURL('/config/server/info'); return this._fetchSharedCacheURL('/config/server/info');
}, },
getProject(project) { getRepo(repo) {
// TODO(kaspern): Rename rest api from /projects/ to /repos/ once backend
// supports it.
return this._fetchSharedCacheURL( return this._fetchSharedCacheURL(
'/projects/' + encodeURIComponent(project)); '/projects/' + encodeURIComponent(repo));
}, },
getProjectConfig(project) { getProjectConfig(repo) {
// TODO(kaspern): Rename rest api from /projects/ to /repos/ once backend
// supports it.
return this._fetchSharedCacheURL( return this._fetchSharedCacheURL(
'/projects/' + encodeURIComponent(project) + '/config'); '/projects/' + encodeURIComponent(repo) + '/config');
}, },
getProjectAccess(project) { getRepoAccess(repo) {
// TODO: Rename rest api from project to repo
// supports it.
return this._fetchSharedCacheURL( return this._fetchSharedCacheURL(
'/access/?project=' + encodeURIComponent(project)); '/access/?project=' + encodeURIComponent(repo));
}, },
saveProjectConfig(project, config, opt_errFn, opt_ctx) { saveRepoConfig(repo, config, opt_errFn, opt_ctx) {
const encodeName = encodeURIComponent(project); // TODO(kaspern): Rename rest api from /projects/ to /repos/ once backend
// supports it.
const encodeName = encodeURIComponent(repo);
return this.send('PUT', `/projects/${encodeName}/config`, config, return this.send('PUT', `/projects/${encodeName}/config`, config,
opt_errFn, opt_ctx); opt_errFn, opt_ctx);
}, },
runProjectGC(project, opt_errFn, opt_ctx) { runRepoGC(repo, opt_errFn, opt_ctx) {
if (!project) { if (!repo) { return ''; }
return ''; // TODO(kaspern): Rename rest api from /projects/ to /repos/ once backend
} // supports it.
const encodeName = encodeURIComponent(project); const encodeName = encodeURIComponent(repo);
return this.send('POST', `/projects/${encodeName}/gc`, '', return this.send('POST', `/projects/${encodeName}/gc`, '',
opt_errFn, opt_ctx); opt_errFn, opt_ctx);
}, },
@ -269,8 +277,10 @@
* @param {function(?Response, string=)=} opt_errFn * @param {function(?Response, string=)=} opt_errFn
* @param {?=} opt_ctx * @param {?=} opt_ctx
*/ */
createProject(config, opt_errFn, opt_ctx) { createRepo(config, opt_errFn, opt_ctx) {
if (!config.name) { return ''; } if (!config.name) { return ''; }
// TODO(kaspern): Rename rest api from /projects/ to /repos/ once backend
// supports it.
const encodeName = encodeURIComponent(config.name); const encodeName = encodeURIComponent(config.name);
return this.send('PUT', `/projects/${encodeName}`, config, opt_errFn, return this.send('PUT', `/projects/${encodeName}`, config, opt_errFn,
opt_ctx); opt_ctx);
@ -294,16 +304,16 @@
}, },
/** /**
* @param {string} project * @param {string} repo
* @param {string} ref * @param {string} ref
* @param {function(?Response, string=)=} opt_errFn * @param {function(?Response, string=)=} opt_errFn
* @param {?=} opt_ctx * @param {?=} opt_ctx
*/ */
deleteProjectBranches(project, ref, opt_errFn, opt_ctx) { deleteRepoBranches(repo, ref, opt_errFn, opt_ctx) {
if (!project || !ref) { if (!repo || !ref) { return ''; }
return ''; // TODO(kaspern): Rename rest api from /projects/ to /repos/ once backend
} // supports it.
const encodeName = encodeURIComponent(project); const encodeName = encodeURIComponent(repo);
const encodeRef = encodeURIComponent(ref); const encodeRef = encodeURIComponent(ref);
return this.send('DELETE', return this.send('DELETE',
`/projects/${encodeName}/branches/${encodeRef}`, '', `/projects/${encodeName}/branches/${encodeRef}`, '',
@ -311,16 +321,16 @@
}, },
/** /**
* @param {string} project * @param {string} repo
* @param {string} ref * @param {string} ref
* @param {function(?Response, string=)=} opt_errFn * @param {function(?Response, string=)=} opt_errFn
* @param {?=} opt_ctx * @param {?=} opt_ctx
*/ */
deleteProjectTags(project, ref, opt_errFn, opt_ctx) { deleteRepoTags(repo, ref, opt_errFn, opt_ctx) {
if (!project || !ref) { if (!repo || !ref) { return ''; }
return ''; // TODO(kaspern): Rename rest api from /projects/ to /repos/ once backend
} // supports it.
const encodeName = encodeURIComponent(project); const encodeName = encodeURIComponent(repo);
const encodeRef = encodeURIComponent(ref); const encodeRef = encodeURIComponent(ref);
return this.send('DELETE', return this.send('DELETE',
`/projects/${encodeName}/tags/${encodeRef}`, '', `/projects/${encodeName}/tags/${encodeRef}`, '',
@ -334,8 +344,10 @@
* @param {function(?Response, string=)=} opt_errFn * @param {function(?Response, string=)=} opt_errFn
* @param {?=} opt_ctx * @param {?=} opt_ctx
*/ */
createProjectBranch(name, branch, revision, opt_errFn, opt_ctx) { createRepoBranch(name, branch, revision, opt_errFn, opt_ctx) {
if (!name || !branch || !revision) { return ''; } if (!name || !branch || !revision) { return ''; }
// TODO(kaspern): Rename rest api from /projects/ to /repos/ once backend
// supports it.
const encodeName = encodeURIComponent(name); const encodeName = encodeURIComponent(name);
const encodeBranch = encodeURIComponent(branch); const encodeBranch = encodeURIComponent(branch);
return this.send('PUT', return this.send('PUT',
@ -350,8 +362,10 @@
* @param {function(?Response, string=)=} opt_errFn * @param {function(?Response, string=)=} opt_errFn
* @param {?=} opt_ctx * @param {?=} opt_ctx
*/ */
createProjectTag(name, tag, revision, opt_errFn, opt_ctx) { createRepoTag(name, tag, revision, opt_errFn, opt_ctx) {
if (!name || !tag || !revision) { return ''; } if (!name || !tag || !revision) { return ''; }
// TODO(kaspern): Rename rest api from /projects/ to /repos/ once backend
// supports it.
const encodeName = encodeURIComponent(name); const encodeName = encodeURIComponent(name);
const encodeTag = encodeURIComponent(tag); const encodeTag = encodeURIComponent(tag);
return this.send('PUT', `/projects/${encodeName}/tags/${encodeTag}`, return this.send('PUT', `/projects/${encodeName}/tags/${encodeTag}`,
@ -1060,54 +1074,62 @@
/** /**
* @param {string} filter * @param {string} filter
* @param {number} projectsPerPage * @param {number} reposPerPage
* @param {number=} opt_offset * @param {number=} opt_offset
* @return {!Promise<?Object>} * @return {!Promise<?Object>}
*/ */
getProjects(filter, projectsPerPage, opt_offset) { getRepos(filter, reposPerPage, opt_offset) {
const offset = opt_offset || 0; const offset = opt_offset || 0;
// TODO(kaspern): Rename rest api from /projects/ to /repos/ once backend
// supports it.
return this._fetchSharedCacheURL( return this._fetchSharedCacheURL(
`/projects/?d&n=${projectsPerPage + 1}&S=${offset}` + `/projects/?d&n=${reposPerPage + 1}&S=${offset}` +
this._computeFilter(filter) this._computeFilter(filter)
); );
}, },
setProjectHead(project, ref) { setRepoHead(repo, ref) {
// TODO(kaspern): Rename rest api from /projects/ to /repos/ once backend
// supports it.
return this.send( return this.send(
'PUT', `/projects/${encodeURIComponent(project)}/HEAD`, {ref}); 'PUT', `/projects/${encodeURIComponent(repo)}/HEAD`, {ref});
}, },
/** /**
* @param {string} filter * @param {string} filter
* @param {string} project * @param {string} repo
* @param {number} projectsBranchesPerPage * @param {number} reposBranchesPerPage
* @param {number=} opt_offset * @param {number=} opt_offset
* @return {!Promise<?Object>} * @return {!Promise<?Object>}
*/ */
getProjectBranches(filter, project, projectsBranchesPerPage, opt_offset) { getRepoBranches(filter, repo, reposBranchesPerPage, opt_offset) {
const offset = opt_offset || 0; const offset = opt_offset || 0;
// TODO(kaspern): Rename rest api from /projects/ to /repos/ once backend
// supports it.
return this.fetchJSON( return this.fetchJSON(
`/projects/${encodeURIComponent(project)}/branches` + `/projects/${encodeURIComponent(repo)}/branches` +
`?n=${projectsBranchesPerPage + 1}&S=${offset}` + `?n=${reposBranchesPerPage + 1}&S=${offset}` +
this._computeFilter(filter) this._computeFilter(filter)
); );
}, },
/** /**
* @param {string} filter * @param {string} filter
* @param {string} project * @param {string} repo
* @param {number} projectsTagsPerPage * @param {number} reposTagsPerPage
* @param {number=} opt_offset * @param {number=} opt_offset
* @return {!Promise<?Object>} * @return {!Promise<?Object>}
*/ */
getProjectTags(filter, project, projectsTagsPerPage, opt_offset) { getRepoTags(filter, repo, reposTagsPerPage, opt_offset) {
const offset = opt_offset || 0; const offset = opt_offset || 0;
// TODO(kaspern): Rename rest api from /projects/ to /repos/ once backend
// supports it.
return this.fetchJSON( return this.fetchJSON(
`/projects/${encodeURIComponent(project)}/tags` + `/projects/${encodeURIComponent(repo)}/tags` +
`?n=${projectsTagsPerPage + 1}&S=${offset}` + `?n=${reposTagsPerPage + 1}&S=${offset}` +
this._computeFilter(filter) this._computeFilter(filter)
); );
}, },
@ -1127,15 +1149,19 @@
); );
}, },
getProjectAccessRights(projectName) { getRepoAccessRights(repoName) {
// TODO(kaspern): Rename rest api from /projects/ to /repos/ once backend
// supports it.
return this._fetchSharedCacheURL( return this._fetchSharedCacheURL(
`/projects/${encodeURIComponent(projectName)}/access`); `/projects/${encodeURIComponent(repoName)}/access`);
}, },
setProjectAccessRights(projectName, projectInfo) { setRepoAccessRights(repoName, repoInfo) {
// TODO(kaspern): Rename rest api from /projects/ to /repos/ once backend
// supports it.
return this.send( return this.send(
'POST', `/projects/${encodeURIComponent(projectName)}/access`, 'POST', `/projects/${encodeURIComponent(repoName)}/access`,
projectInfo); repoInfo);
}, },
setProjectAccessRightsForReview(projectName, projectInfo) { setProjectAccessRightsForReview(projectName, projectInfo) {

View File

@ -799,9 +799,9 @@ limitations under the License.
{reason: 'removal reason'})); {reason: 'removal reason'}));
}); });
test('createProject encodes name', () => { test('createRepo encodes name', () => {
const sendStub = sandbox.stub(element, 'send'); const sendStub = sandbox.stub(element, 'send');
element.createProject({name: 'x/y'}); element.createRepo({name: 'x/y'});
assert.equal(sendStub.lastCall.args[1], '/projects/x%2Fy'); assert.equal(sendStub.lastCall.args[1], '/projects/x%2Fy');
}); });
@ -814,31 +814,31 @@ limitations under the License.
}); });
}); });
test('getProjects', () => { test('getRepos', () => {
sandbox.stub(element, '_fetchSharedCacheURL'); sandbox.stub(element, '_fetchSharedCacheURL');
element.getProjects('test', 25); element.getRepos('test', 25);
assert.isTrue(element._fetchSharedCacheURL.lastCall assert.isTrue(element._fetchSharedCacheURL.lastCall
.calledWithExactly('/projects/?d&n=26&S=0&m=test')); .calledWithExactly('/projects/?d&n=26&S=0&m=test'));
element.getProjects(null, 25); element.getRepos(null, 25);
assert.isTrue(element._fetchSharedCacheURL.lastCall assert.isTrue(element._fetchSharedCacheURL.lastCall
.calledWithExactly('/projects/?d&n=26&S=0')); .calledWithExactly('/projects/?d&n=26&S=0'));
element.getProjects('test', 25, 25); element.getRepos('test', 25, 25);
assert.isTrue(element._fetchSharedCacheURL.lastCall assert.isTrue(element._fetchSharedCacheURL.lastCall
.calledWithExactly('/projects/?d&n=26&S=25&m=test')); .calledWithExactly('/projects/?d&n=26&S=25&m=test'));
}); });
test('getProjects filter', () => { test('getRepos filter', () => {
sandbox.stub(element, '_fetchSharedCacheURL'); sandbox.stub(element, '_fetchSharedCacheURL');
element.getProjects('test/test/test', 25); element.getRepos('test/test/test', 25);
assert.isTrue(element._fetchSharedCacheURL.lastCall assert.isTrue(element._fetchSharedCacheURL.lastCall
.calledWithExactly('/projects/?d&n=26&S=0&m=test%2Ftest%2Ftest')); .calledWithExactly('/projects/?d&n=26&S=0&m=test%2Ftest%2Ftest'));
}); });
test('getProjects filter regex', () => { test('getRepos filter regex', () => {
sandbox.stub(element, '_fetchSharedCacheURL'); sandbox.stub(element, '_fetchSharedCacheURL');
element.getProjects('^test.*', 25); element.getRepos('^test.*', 25);
assert.isTrue(element._fetchSharedCacheURL.lastCall assert.isTrue(element._fetchSharedCacheURL.lastCall
.calledWithExactly('/projects/?d&n=26&S=0&r=%5Etest.*')); .calledWithExactly('/projects/?d&n=26&S=0&r=%5Etest.*'));
}); });

View File

@ -1,10 +1,10 @@
<dom-module id="sample-project-command"> <dom-module id="sample-repo-command">
<script> <script>
Gerrit.install(plugin => { Gerrit.install(plugin => {
// High-level API // High-level API
plugin.project() plugin.project()
.createCommand('Bork', (projectName, projectConfig) => { .createCommand('Bork', (repoName, projectConfig) => {
if (projectName !== 'All-Projects') { if (repoName !== 'All-Projects') {
return false; return false;
} }
}).onTap(() => { }).onTap(() => {
@ -13,26 +13,26 @@
// Low-level API // Low-level API
plugin.registerCustomComponent( plugin.registerCustomComponent(
'project-command', 'project-command-low'); 'repo-command', 'repo-command-low');
}); });
</script> </script>
</dom-module> </dom-module>
<!-- Low-level custom component for project command. --> <!-- Low-level custom component for repo command. -->
<dom-module id="project-command-low"> <dom-module id="repo-command-low">
<template> <template>
<gr-project-command <gr-repo-command
title="Low-level bork" title="Low-level bork"
on-command-tap="_handleCommandTap"> on-command-tap="_handleCommandTap">
</gr-project-command> </gr-repo-command>
</template> </template>
<script> <script>
Polymer({ Polymer({
is: 'project-command-low', is: 'repo-command-low',
attached() { attached() {
console.log(this.projectName); console.log(this.repoName);
console.log(this.config); console.log(this.config);
this.hidden = this.projectName !== 'All-Projects'; this.hidden = this.repoName !== 'All-Projects';
}, },
_handleCommandTap() { _handleCommandTap() {
alert('(softly) bork, bork.'); alert('(softly) bork, bork.');

View File

@ -38,18 +38,18 @@ limitations under the License.
'admin/gr-create-change-dialog/gr-create-change-dialog_test.html', 'admin/gr-create-change-dialog/gr-create-change-dialog_test.html',
'admin/gr-create-group-dialog/gr-create-group-dialog_test.html', 'admin/gr-create-group-dialog/gr-create-group-dialog_test.html',
'admin/gr-create-pointer-dialog/gr-create-pointer-dialog_test.html', 'admin/gr-create-pointer-dialog/gr-create-pointer-dialog_test.html',
'admin/gr-create-project-dialog/gr-create-project-dialog_test.html', 'admin/gr-create-repo-dialog/gr-create-repo-dialog_test.html',
'admin/gr-group-audit-log/gr-group-audit-log_test.html', 'admin/gr-group-audit-log/gr-group-audit-log_test.html',
'admin/gr-group-members/gr-group-members_test.html', 'admin/gr-group-members/gr-group-members_test.html',
'admin/gr-group/gr-group_test.html', 'admin/gr-group/gr-group_test.html',
'admin/gr-permission/gr-permission_test.html', 'admin/gr-permission/gr-permission_test.html',
'admin/gr-plugin-list/gr-plugin-list_test.html', 'admin/gr-plugin-list/gr-plugin-list_test.html',
'admin/gr-project-access/gr-project-access_test.html', 'admin/gr-repo-access/gr-repo-access_test.html',
'admin/gr-project-command/gr-project-command_test.html', 'admin/gr-repo-command/gr-repo-command_test.html',
'admin/gr-project-commands/gr-project-commands_test.html', 'admin/gr-repo-commands/gr-repo-commands_test.html',
'admin/gr-project-detail-list/gr-project-detail-list_test.html', 'admin/gr-repo-detail-list/gr-repo-detail-list_test.html',
'admin/gr-project-list/gr-project-list_test.html', 'admin/gr-repo-list/gr-repo-list_test.html',
'admin/gr-project/gr-project_test.html', 'admin/gr-repo/gr-repo_test.html',
'admin/gr-rule-editor/gr-rule-editor_test.html', 'admin/gr-rule-editor/gr-rule-editor_test.html',
'change-list/gr-change-list-item/gr-change-list-item_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-view/gr-change-list-view_test.html',
@ -112,10 +112,10 @@ limitations under the License.
'plugins/gr-endpoint-decorator/gr-endpoint-decorator_test.html', 'plugins/gr-endpoint-decorator/gr-endpoint-decorator_test.html',
'plugins/gr-event-helper/gr-event-helper_test.html', 'plugins/gr-event-helper/gr-event-helper_test.html',
'plugins/gr-external-style/gr-external-style_test.html', 'plugins/gr-external-style/gr-external-style_test.html',
'plugins/gr-project-api/gr-project-api_test.html',
'plugins/gr-plugin-host/gr-plugin-host_test.html', 'plugins/gr-plugin-host/gr-plugin-host_test.html',
'plugins/gr-popup-interface/gr-plugin-popup_test.html', 'plugins/gr-popup-interface/gr-plugin-popup_test.html',
'plugins/gr-popup-interface/gr-popup-interface_test.html', 'plugins/gr-popup-interface/gr-popup-interface_test.html',
'plugins/gr-repo-api/gr-repo-api_test.html',
'settings/gr-account-info/gr-account-info_test.html', 'settings/gr-account-info/gr-account-info_test.html',
'settings/gr-change-table-editor/gr-change-table-editor_test.html', 'settings/gr-change-table-editor/gr-change-table-editor_test.html',
'settings/gr-email-editor/gr-email-editor_test.html', 'settings/gr-email-editor/gr-email-editor_test.html',