Merge "Add support for deleting tags through the web ui"
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/GerritConstants.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/GerritConstants.java
index a850a9b..b44cd1c 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/GerritConstants.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/GerritConstants.java
@@ -57,6 +57,10 @@
String branchDeletionConfirmationMessage();
+ String tagDeletionDialogTitle();
+
+ String tagDeletionConfirmationMessage();
+
String newUi();
String notSignedInTitle();
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/GerritConstants.properties b/gerrit-gwtui/src/main/java/com/google/gerrit/client/GerritConstants.properties
index cab988b..9aa4388 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/GerritConstants.properties
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/GerritConstants.properties
@@ -26,6 +26,9 @@
branchDeletionDialogTitle = Branch Deletion
branchDeletionConfirmationMessage = Do you really want to delete the following branches?
+tagDeletionDialogTitle = Tag Deletion
+tagDeletionConfirmationMessage = Do you really want to delete the following tags?
+
newUi = New UI
notSignedInTitle = Code Review - Session Expired
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/AdminConstants.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/AdminConstants.java
index d4b575f..d7fb072 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/AdminConstants.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/AdminConstants.java
@@ -185,6 +185,8 @@
String buttonAddTag();
+ String buttonDeleteTag();
+
String saveHeadButton();
String cancelHeadButton();
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/AdminConstants.properties b/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/AdminConstants.properties
index 404d903..465bcfc 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/AdminConstants.properties
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/AdminConstants.properties
@@ -88,6 +88,7 @@
buttonAddBranch = Create Branch
buttonAddTag = Create Tag
buttonDeleteBranch = Delete
+buttonDeleteTag = Delete
saveHeadButton = Save
cancelHeadButton = Cancel
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/ProjectTagsScreen.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/ProjectTagsScreen.java
index de40a5d..b89139c 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/ProjectTagsScreen.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/ProjectTagsScreen.java
@@ -20,6 +20,7 @@
import com.google.gerrit.client.ConfirmationDialog;
import com.google.gerrit.client.ErrorDialog;
import com.google.gerrit.client.Gerrit;
+import com.google.gerrit.client.VoidResult;
import com.google.gerrit.client.access.AccessMap;
import com.google.gerrit.client.access.ProjectAccessInfo;
import com.google.gerrit.client.projects.ProjectApi;
@@ -43,6 +44,8 @@
import com.google.gwt.event.dom.client.KeyPressHandler;
import com.google.gwt.event.dom.client.KeyUpEvent;
import com.google.gwt.event.dom.client.KeyUpHandler;
+import com.google.gwt.event.logical.shared.ValueChangeEvent;
+import com.google.gwt.event.logical.shared.ValueChangeHandler;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.CheckBox;
import com.google.gwt.user.client.ui.FlexTable.FlexCellFormatter;
@@ -52,6 +55,7 @@
import com.google.gwt.user.client.ui.InlineHTML;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.TextBox;
+import com.google.gwt.user.client.ui.Widget;
import com.google.gwtexpui.globalkey.client.NpTextBox;
import com.google.gwtexpui.safehtml.client.SafeHtmlBuilder;
import java.util.HashSet;
@@ -62,6 +66,7 @@
private Hyperlink prev;
private Hyperlink next;
private TagsTable tagTable;
+ private Button delTag;
private Button addTag;
private HintTextBox nameTxtBox;
private HintTextBox irevTxtBox;
@@ -95,6 +100,7 @@
}
private void updateForm() {
+ tagTable.updateDeleteButton();
addTag.setEnabled(true);
nameTxtBox.setEnabled(true);
irevTxtBox.setEnabled(true);
@@ -160,8 +166,19 @@
tagTable = new TagsTable();
+ delTag = new Button(AdminConstants.I.buttonDeleteTag());
+ delTag.setStyleName(Gerrit.RESOURCES.css().branchTableDeleteButton());
+ delTag.addClickHandler(
+ new ClickHandler() {
+ @Override
+ public void onClick(ClickEvent event) {
+ tagTable.deleteChecked();
+ }
+ });
+
HorizontalPanel buttons = new HorizontalPanel();
buttons.setStyleName(Gerrit.RESOURCES.css().branchTablePrevNextLinks());
+ buttons.add(delTag);
buttons.add(prev);
buttons.add(next);
add(tagTable);
@@ -272,6 +289,8 @@
}
private class TagsTable extends NavigationTable<TagInfo> {
+ private ValueChangeHandler<Boolean> updateDeleteHandler;
+ boolean canDelete;
TagsTable() {
table.setWidth("");
@@ -282,6 +301,14 @@
fmt.addStyleName(0, 1, Gerrit.RESOURCES.css().iconHeader());
fmt.addStyleName(0, 2, Gerrit.RESOURCES.css().dataHeader());
fmt.addStyleName(0, 3, Gerrit.RESOURCES.css().dataHeader());
+
+ updateDeleteHandler =
+ new ValueChangeHandler<Boolean>() {
+ @Override
+ public void onValueChange(ValueChangeEvent<Boolean> event) {
+ updateDeleteButton();
+ }
+ };
}
Set<String> getCheckedRefs() {
@@ -306,11 +333,74 @@
}
}
+ void deleteChecked() {
+ final Set<String> refs = getCheckedRefs();
+
+ SafeHtmlBuilder b = new SafeHtmlBuilder();
+ b.openElement("b");
+ b.append(Gerrit.C.tagDeletionConfirmationMessage());
+ b.closeElement("b");
+
+ b.openElement("p");
+ boolean first = true;
+ for (String ref : refs) {
+ if (!first) {
+ b.append(",").br();
+ }
+ b.append(ref);
+ first = false;
+ }
+ b.closeElement("p");
+
+ if (refs.isEmpty()) {
+ updateDeleteButton();
+ return;
+ }
+
+ delTag.setEnabled(false);
+ ConfirmationDialog confirmationDialog =
+ new ConfirmationDialog(
+ Gerrit.C.tagDeletionDialogTitle(),
+ b.toSafeHtml(),
+ new ConfirmationCallback() {
+ @Override
+ public void onOk() {
+ deleteTags(refs);
+ }
+
+ @Override
+ public void onCancel() {
+ tagTable.updateDeleteButton();
+ }
+ });
+ confirmationDialog.center();
+ }
+
+ private void deleteTags(final Set<String> tags) {
+ ProjectApi.deleteTags(
+ getProjectKey(),
+ tags,
+ new GerritCallback<VoidResult>() {
+ @Override
+ public void onSuccess(VoidResult result) {
+ query = new Query(match).start(start).run();
+ }
+
+ @Override
+ public void onFailure(Throwable caught) {
+ query = new Query(match).start(start).run();
+ super.onFailure(caught);
+ }
+ });
+ }
+
void display(List<TagInfo> tags) {
displaySubset(tags, 0, tags.size());
}
void displaySubset(List<TagInfo> tags, int fromIndex, int toIndex) {
+ canDelete = false;
+
while (1 < table.getRowCount()) {
table.removeRow(table.getRowCount() - 1);
}
@@ -324,7 +414,14 @@
}
void populate(int row, TagInfo k) {
- table.setText(row, 1, "");
+ if (k.canDelete()) {
+ CheckBox sel = new CheckBox();
+ sel.addValueChangeHandler(updateDeleteHandler);
+ table.setWidget(row, 1, sel);
+ canDelete = true;
+ } else {
+ table.setText(row, 1, "");
+ }
table.setWidget(row, 2, new InlineHTML(highlight(k.getShortName(), match)));
@@ -344,6 +441,25 @@
setRowItem(row, k);
}
+ boolean hasTagCanDelete() {
+ return canDelete;
+ }
+
+ void updateDeleteButton() {
+ boolean on = false;
+ for (int row = 1; row < table.getRowCount(); row++) {
+ Widget w = table.getWidget(row, 1);
+ if (w != null && w instanceof CheckBox) {
+ CheckBox sel = (CheckBox) w;
+ if (sel.getValue()) {
+ on = true;
+ break;
+ }
+ }
+ }
+ delTag.setEnabled(on);
+ }
+
@Override
protected void onOpenRow(int row) {
if (row > 0) {
@@ -421,6 +537,7 @@
prev.setVisible(false);
}
+ delTag.setVisible(tagTable.hasTagCanDelete());
Set<String> checkedRefs = tagTable.getCheckedRefs();
tagTable.setChecked(checkedRefs);
updateForm();
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/projects/ProjectApi.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/projects/ProjectApi.java
index 1350e1a..4be877e 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/projects/ProjectApi.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/projects/ProjectApi.java
@@ -82,6 +82,20 @@
getRestApi(name, "tags", limit, start, match).get(cb);
}
+ /** Delete tags. One call is fired to the server to delete all the tags. */
+ public static void deleteTags(
+ Project.NameKey name, Set<String> refs, AsyncCallback<VoidResult> cb) {
+ if (refs.size() == 1) {
+ project(name).view("tags").id(refs.iterator().next()).delete(cb);
+ } else {
+ DeleteTagsInput d = DeleteTagsInput.create();
+ for (String ref : refs) {
+ d.addTag(ref);
+ }
+ project(name).view("tags:delete").post(d, cb);
+ }
+ }
+
/** Create a new branch */
public static void createBranch(
Project.NameKey name, String ref, String revision, AsyncCallback<BranchInfo> cb) {
@@ -373,6 +387,20 @@
final native void setRef(String r) /*-{ if(r)this.ref=r; }-*/;
}
+ private static class DeleteTagsInput extends JavaScriptObject {
+ static DeleteTagsInput create() {
+ DeleteTagsInput d = createObject().cast();
+ d.init();
+ return d;
+ }
+
+ protected DeleteTagsInput() {}
+
+ final native void init() /*-{ this.tags = []; }-*/;
+
+ final native void addTag(String b) /*-{ this.tags.push(b); }-*/;
+ }
+
private static class DeleteBranchesInput extends JavaScriptObject {
static DeleteBranchesInput create() {
DeleteBranchesInput d = createObject().cast();
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/projects/TagInfo.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/projects/TagInfo.java
index bccac9b..24487ae 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/projects/TagInfo.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/projects/TagInfo.java
@@ -15,6 +15,8 @@
package com.google.gerrit.client.projects;
public class TagInfo extends RefInfo {
+ public final native boolean canDelete() /*-{ return this['can_delete'] ? true : false; }-*/;
+
// TODO(dpursehouse) add extra tag-related fields (message, tagger, etc)
protected TagInfo() {}
}