PolyGerrit: Support deleting tags / branches from gr-project-detail-list
Change-Id: I2fa4a4072e4d3f508cc59487963336fa28a85b5b
diff --git a/polygerrit-ui/app/elements/admin/gr-confirm-delete-item-dialog/gr-confirm-delete-item-dialog.html b/polygerrit-ui/app/elements/admin/gr-confirm-delete-item-dialog/gr-confirm-delete-item-dialog.html
new file mode 100644
index 0000000..e132100
--- /dev/null
+++ b/polygerrit-ui/app/elements/admin/gr-confirm-delete-item-dialog/gr-confirm-delete-item-dialog.html
@@ -0,0 +1,45 @@
+<!--
+Copyright (C) 2017 The Android Open Source Project
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+-->
+
+<link rel="import" href="../../../bower_components/polymer/polymer.html">
+<link rel="import" href="../../shared/gr-confirm-dialog/gr-confirm-dialog.html">
+<link rel="import" href="../../../styles/shared-styles.html">
+
+<dom-module id="gr-confirm-delete-item-dialog">
+ <template>
+ <style include="shared-styles">
+ :host {
+ display: block;
+ width: 30em;
+ }
+ </style>
+ <gr-confirm-dialog
+ confirm-label="Delete [[_computeItemName(itemType)]]"
+ on-confirm="_handleConfirmTap"
+ on-cancel="_handleCancelTap">
+ <div class="header">[[_computeItemName(itemType)]] Deletion</div>
+ <div class="main">
+ <label for="branchInput">
+ Do you really want to delete the following [[_computeItemName(itemType)]]?
+ </label>
+ <div>
+ [[item]]
+ </div>
+ </div>
+ </gr-confirm-dialog>
+ </template>
+ <script src="gr-confirm-delete-item-dialog.js"></script>
+</dom-module>
diff --git a/polygerrit-ui/app/elements/admin/gr-confirm-delete-item-dialog/gr-confirm-delete-item-dialog.js b/polygerrit-ui/app/elements/admin/gr-confirm-delete-item-dialog/gr-confirm-delete-item-dialog.js
new file mode 100644
index 0000000..ddc98e9
--- /dev/null
+++ b/polygerrit-ui/app/elements/admin/gr-confirm-delete-item-dialog/gr-confirm-delete-item-dialog.js
@@ -0,0 +1,62 @@
+// Copyright (C) 2017 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+(function() {
+ 'use strict';
+
+ const DETAIL_TYPES = {
+ BRANCHES: 'branches',
+ TAGS: 'tags',
+ };
+
+ Polymer({
+ is: 'gr-confirm-delete-item-dialog',
+
+ /**
+ * Fired when the confirm button is pressed.
+ *
+ * @event confirm
+ */
+
+ /**
+ * Fired when the cancel button is pressed.
+ *
+ * @event cancel
+ */
+
+ properties: {
+ item: String,
+ itemType: String,
+ },
+
+ _handleConfirmTap(e) {
+ e.preventDefault();
+ e.stopPropagation();
+ this.fire('confirm', null, {bubbles: false});
+ },
+
+ _handleCancelTap(e) {
+ e.preventDefault();
+ e.stopPropagation();
+ this.fire('cancel', null, {bubbles: false});
+ },
+
+ _computeItemName(detailType) {
+ if (detailType === DETAIL_TYPES.BRANCHES) {
+ return 'Branch';
+ } else if (detailType === DETAIL_TYPES.TAGS) {
+ return 'Tag';
+ }
+ },
+ });
+})();
\ No newline at end of file
diff --git a/polygerrit-ui/app/elements/admin/gr-confirm-delete-item-dialog/gr-confirm-delete-item-dialog_test.html b/polygerrit-ui/app/elements/admin/gr-confirm-delete-item-dialog/gr-confirm-delete-item-dialog_test.html
new file mode 100644
index 0000000..8671ad1
--- /dev/null
+++ b/polygerrit-ui/app/elements/admin/gr-confirm-delete-item-dialog/gr-confirm-delete-item-dialog_test.html
@@ -0,0 +1,76 @@
+<!DOCTYPE html>
+<!--
+Copyright (C) 2017 The Android Open Source Project
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+-->
+
+<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
+<title>gr-confirm-delete-item-dialog</title>
+
+<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
+<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<link rel="import" href="../../../test/common-test-setup.html"/>
+<link rel="import" href="gr-confirm-delete-item-dialog.html">
+
+<script>void(0);</script>
+
+<test-fixture id="basic">
+ <template>
+ <gr-confirm-delete-item-dialog></gr-confirm-delete-item-dialog>
+ </template>
+</test-fixture>
+
+<script>
+ suite('gr-confirm-delete-item-dialog tests', () => {
+ let element;
+ let sandbox;
+
+ setup(() => {
+ sandbox = sinon.sandbox.create();
+ element = fixture('basic');
+ });
+
+ teardown(() => {
+ sandbox.restore();
+ });
+
+ test('_handleConfirmTap', () => {
+ const confirmHandler = sandbox.stub();
+ element.addEventListener('confirm', confirmHandler);
+ sandbox.stub(element, '_handleConfirmTap');
+ element.$$('gr-confirm-dialog').fire('confirm');
+ assert.isTrue(confirmHandler.called);
+ assert.isTrue(element._handleConfirmTap.called);
+ });
+
+ test('_handleCancelTap', () => {
+ const cancelHandler = sandbox.stub();
+ element.addEventListener('cancel', cancelHandler);
+ sandbox.stub(element, '_handleCancelTap');
+ element.$$('gr-confirm-dialog').fire('cancel');
+ assert.isTrue(cancelHandler.called);
+ assert.isTrue(element._handleCancelTap.called);
+ });
+
+ test('_computeItemName function for branches', () => {
+ assert.deepEqual(element._computeItemName('branches'), 'Branch');
+ assert.notEqual(element._computeItemName('branches'), 'Tag');
+ });
+
+ test('_computeItemName function for tags', () => {
+ assert.deepEqual(element._computeItemName('tags'), 'Tag');
+ assert.notEqual(element._computeItemName('tags'), 'Branch');
+ });
+ });
+</script>
diff --git a/polygerrit-ui/app/elements/admin/gr-project-detail-list/gr-project-detail-list.html b/polygerrit-ui/app/elements/admin/gr-project-detail-list/gr-project-detail-list.html
index 23f31fa..f480908 100644
--- a/polygerrit-ui/app/elements/admin/gr-project-detail-list/gr-project-detail-list.html
+++ b/polygerrit-ui/app/elements/admin/gr-project-detail-list/gr-project-detail-list.html
@@ -19,12 +19,13 @@
<link rel="import" href="../../../bower_components/iron-input/iron-input.html">
<link rel="import" href="../../../bower_components/polymer/polymer.html">
<link rel="import" href="../../../styles/gr-table-styles.html">
-<link rel="import" href="../../shared/gr-button/gr-button.html">
-<link rel="import" href="../../shared/gr-rest-api-interface/gr-rest-api-interface.html">
-
<link rel="import" href="../../../styles/gr-form-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-list-view/gr-list-view.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="../gr-confirm-delete-item-dialog/gr-confirm-delete-item-dialog.html">
<dom-module id="gr-project-detail-list">
<template>
@@ -52,6 +53,9 @@
display: flex;
line-height: 1em;
}
+ .deleteButton:not(.show) {
+ display: none;
+ }
</style>
<style include="gr-table-styles"></style>
<gr-list-view
@@ -67,6 +71,7 @@
<th class="description topHeader">Revision</th>
<th class$="repositoryBrowser topHeader [[computeBrowserClass(detailType)]]">
Repository Browser</th>
+ <th class="delete topHeader"></th>
</tr>
<tr id="loading" class$="loadingMsg [[computeLoadingClass(_loading)]]">
<td>Loading...</td>
@@ -116,10 +121,25 @@
</a>
</template>
</td>
+ <td class="delete">
+ <gr-button
+ class$="deleteButton [[_computeHideDeleteClass(_isOwner, item.can_delete)]]"
+ on-tap="_handleDeleteItem">
+ Delete
+ </gr-button>
+ </td>
</tr>
</template>
</tbody>
</table>
+ <gr-overlay id="overlay" with-backdrop>
+ <gr-confirm-delete-item-dialog
+ class="confirmDialog"
+ on-confirm="_handleDeleteItemConfirm"
+ on-cancel="_handleConfirmDialogCancel"
+ item="[[_refName]]"
+ item-type="[[detailType]]"></gr-confirm-delete-item-dialog>
+ </gr-overlay>
</gr-list-view>
<gr-rest-api-interface id="restAPI"></gr-rest-api-interface>
</template>
diff --git a/polygerrit-ui/app/elements/admin/gr-project-detail-list/gr-project-detail-list.js b/polygerrit-ui/app/elements/admin/gr-project-detail-list/gr-project-detail-list.js
index edaf49a..8c2f743 100644
--- a/polygerrit-ui/app/elements/admin/gr-project-detail-list/gr-project-detail-list.js
+++ b/polygerrit-ui/app/elements/admin/gr-project-detail-list/gr-project-detail-list.js
@@ -67,6 +67,7 @@
value: true,
},
_filter: String,
+ _refName: String,
},
behaviors: [
@@ -83,7 +84,6 @@
},
_paramsChanged(params) {
- this._loading = true;
if (!params || !params.project) { return; }
this._project = params.project;
@@ -99,6 +99,7 @@
},
_getItems(filter, project, itemsPerPage, offset, detailType) {
+ this._loading = true;
this._items = [];
Polymer.dom.flush();
if (detailType === DETAIL_TYPES.BRANCHES) {
@@ -157,8 +158,8 @@
'canEdit' : '';
},
- _handleEditRevision() {
- this._revisedRef = event.model.get('item.revision');
+ _handleEditRevision(e) {
+ this._revisedRef = e.model.get('item.revision');
this._isEditing = true;
},
@@ -170,13 +171,64 @@
this._setProjectHead(this._project, this._revisedRef, e);
},
- _setProjectHead(project, ref, event) {
+ _setProjectHead(project, ref, e) {
return this.$.restAPI.setProjectHead(project, ref).then(res => {
if (res.status < 400) {
this._isEditing = false;
- event.model.set('item.revision', ref);
+ e.model.set('item.revision', ref);
}
});
},
+
+ _computeItemName(detailType) {
+ if (detailType === DETAIL_TYPES.BRANCHES) {
+ return 'Branch';
+ } else if (detailType === DETAIL_TYPES.TAGS) {
+ return 'Tag';
+ }
+ },
+
+ _handleDeleteItemConfirm() {
+ this.$.overlay.close();
+ if (this.detailType === DETAIL_TYPES.BRANCHES) {
+ return this.$.restAPI.deleteProjectBranches(this._project,
+ this._refName)
+ .then(itemDeleted => {
+ if (itemDeleted.status === 204) {
+ this._getItems(
+ this._filter, this._project, this._itemsPerPage,
+ this._offset, this.detailType);
+ }
+ });
+ } else if (this.detailType === DETAIL_TYPES.TAGS) {
+ return this.$.restAPI.deleteProjectTags(this._project,
+ this._refName)
+ .then(itemDeleted => {
+ if (itemDeleted.status === 204) {
+ this._getItems(
+ this._filter, this._project, this._itemsPerPage,
+ this._offset, this.detailType);
+ }
+ });
+ }
+ },
+
+ _handleConfirmDialogCancel() {
+ this.$.overlay.close();
+ },
+
+ _handleDeleteItem(e) {
+ const name = this._stripRefs(e.model.get('item.ref'), this.detailType);
+ if (!name) { return; }
+ this._refName = name;
+ this.$.overlay.open();
+ },
+
+ _computeHideDeleteClass(owner, deleteRef) {
+ if (owner && !deleteRef || owner && deleteRef || deleteRef || owner) {
+ return 'show';
+ }
+ return '';
+ },
});
})();
diff --git a/polygerrit-ui/app/elements/admin/gr-project-detail-list/gr-project-detail-list_test.html b/polygerrit-ui/app/elements/admin/gr-project-detail-list/gr-project-detail-list_test.html
index dfe3bd8..c36115d 100644
--- a/polygerrit-ui/app/elements/admin/gr-project-detail-list/gr-project-detail-list_test.html
+++ b/polygerrit-ui/app/elements/admin/gr-project-detail-list/gr-project-detail-list_test.html
@@ -248,6 +248,11 @@
done();
});
});
+
+ test('test _computeItemName', () => {
+ assert.deepEqual(element._computeItemName('branches'), 'Branch');
+ assert.deepEqual(element._computeItemName('tags'), 'Tag');
+ });
});
suite('list with less then 25 branches', () => {
diff --git a/polygerrit-ui/app/elements/shared/gr-rest-api-interface/gr-rest-api-interface.js b/polygerrit-ui/app/elements/shared/gr-rest-api-interface/gr-rest-api-interface.js
index 0d77e87..0c8bfd8 100644
--- a/polygerrit-ui/app/elements/shared/gr-rest-api-interface/gr-rest-api-interface.js
+++ b/polygerrit-ui/app/elements/shared/gr-rest-api-interface/gr-rest-api-interface.js
@@ -223,6 +223,28 @@
return this._fetchSharedCacheURL('/groups/' + encodeName + '/detail');
},
+ deleteProjectBranches(project, ref, opt_errFn, opt_ctx) {
+ if (!project || !ref) {
+ return '';
+ }
+ const encodeName = encodeURIComponent(project);
+ const encodeRef = encodeURIComponent(ref);
+ return this.send('DELETE',
+ `/projects/${encodeName}/branches/${encodeRef}`, '',
+ opt_errFn, opt_ctx);
+ },
+
+ deleteProjectTags(project, ref, opt_errFn, opt_ctx) {
+ if (!project || !ref) {
+ return '';
+ }
+ const encodeName = encodeURIComponent(project);
+ const encodeRef = encodeURIComponent(ref);
+ return this.send('DELETE',
+ `/projects/${encodeName}/tags/${encodeRef}`, '',
+ opt_errFn, opt_ctx);
+ },
+
getVersion() {
return this._fetchSharedCacheURL('/config/server/version');
},
@@ -626,7 +648,7 @@
getProjectBranches(filter, project, projectsBranchesPerPage, opt_offset) {
const offset = opt_offset || 0;
- return this._fetchSharedCacheURL(
+ return this.fetchJSON(
`/projects/${encodeURIComponent(project)}/branches` +
`?n=${projectsBranchesPerPage + 1}&s=${offset}` +
this._computeFilter(filter)
@@ -636,7 +658,7 @@
getProjectTags(filter, project, projectsTagsPerPage, opt_offset) {
const offset = opt_offset || 0;
- return this._fetchSharedCacheURL(
+ return this.fetchJSON(
`/projects/${encodeURIComponent(project)}/tags` +
`?n=${projectsTagsPerPage + 1}&s=${offset}` +
this._computeFilter(filter)
diff --git a/polygerrit-ui/app/test/index.html b/polygerrit-ui/app/test/index.html
index da4ad2e..d313274 100644
--- a/polygerrit-ui/app/test/index.html
+++ b/polygerrit-ui/app/test/index.html
@@ -34,6 +34,7 @@
'admin/gr-admin-plugin-list/gr-admin-plugin-list_test.html',
'admin/gr-admin-project-list/gr-admin-project-list_test.html',
'admin/gr-admin-view/gr-admin-view_test.html',
+ 'admin/gr-confirm-delete-item-dialog/gr-confirm-delete-item-dialog_test.html',
'admin/gr-create-group-dialog/gr-create-group-dialog_test.html',
'admin/gr-create-project-dialog/gr-create-project-dialog_test.html',
'admin/gr-project/gr-project_test.html',