Removing all RPC calls for watching projects

This change migrates the GWT UI towards using the new REST endpoints for
all requests related to watching projects. This will remove unnecessary
RPC requests.

Change-Id: Ib59fe170dcd6c22aceab9ccb6434f065319a31f7
This commit is contained in:
Patrick Hiesel
2016-05-06 14:29:24 +02:00
committed by Edwin Kempin
parent 7eea8e6bff
commit 96918cce97
7 changed files with 201 additions and 247 deletions

View File

@@ -27,6 +27,7 @@ import com.google.gwt.core.client.JsArray;
import com.google.gwt.core.client.JsArrayString;
import com.google.gwt.user.client.rpc.AsyncCallback;
import java.util.HashSet;
import java.util.Set;
/**
@@ -108,6 +109,54 @@ public class AccountApi {
.post(sshPublicKey, cb);
}
/** Retrieve Watched Projects */
public static void getWatchedProjects(String account,
AsyncCallback<JsArray<ProjectWatchInfo>> cb) {
new RestApi("/accounts/").id(account).view("watched.projects").get(cb);
}
/** Create/Update Watched Project */
public static void updateWatchedProject(
String account,
ProjectWatchInfo watchedProjectInfo,
AsyncCallback<JsArray<ProjectWatchInfo>> cb) {
Set<ProjectWatchInfo> watchedProjectInfos = new HashSet<>();
watchedProjectInfos.add(watchedProjectInfo);
updateWatchedProjects(account, watchedProjectInfos, cb);
}
/** Create/Update Watched Projects */
public static void updateWatchedProjects(
String account,
Set<ProjectWatchInfo> watchedProjectInfos,
AsyncCallback<JsArray<ProjectWatchInfo>> cb) {
new RestApi("/accounts/")
.id(account)
.view("watched.projects")
.post(projectWatchArrayFromSet(watchedProjectInfos), cb);
}
/** Delete Watched Project */
public static void deleteWatchedProject(
String account,
ProjectWatchInfo watchedProjectInfo,
AsyncCallback<JsArray<ProjectWatchInfo>> cb) {
Set<ProjectWatchInfo> watchedProjectInfos = new HashSet<>();
watchedProjectInfos.add(watchedProjectInfo);
deleteWatchedProjects(account, watchedProjectInfos, cb);
}
/** Delete Watched Projects */
public static void deleteWatchedProjects(
String account,
Set<ProjectWatchInfo> watchedProjectInfos,
AsyncCallback<JsArray<ProjectWatchInfo>> cb) {
new RestApi("/accounts/")
.id(account)
.view("watched.projects:delete")
.post(projectWatchArrayFromSet(watchedProjectInfos), cb);
}
/**
* Delete SSH keys. For each key to be deleted a separate DELETE request is
* fired to the server. The {@code onSuccess} method of the provided callback
@@ -146,6 +195,15 @@ public class AccountApi {
new RestApi("/accounts/").id(account).view("password.http").delete(cb);
}
private static JsArray<ProjectWatchInfo> projectWatchArrayFromSet(
Set<ProjectWatchInfo> set) {
JsArray<ProjectWatchInfo> jsArray = JsArray.createArray().cast();
for (ProjectWatchInfo p : set) {
jsArray.push(p);
}
return jsArray;
}
private static class HttpPasswordInput extends JavaScriptObject {
final native void generate(boolean g) /*-{ if(g)this.generate=g; }-*/;

View File

@@ -16,13 +16,13 @@ package com.google.gerrit.client.account;
import com.google.gerrit.client.Gerrit;
import com.google.gerrit.client.rpc.GerritCallback;
import com.google.gerrit.client.rpc.ScreenLoadCallback;
import com.google.gerrit.client.ui.HintTextBox;
import com.google.gerrit.client.ui.ProjectListPopup;
import com.google.gerrit.client.ui.ProjectNameSuggestOracle;
import com.google.gerrit.client.ui.RemoteSuggestBox;
import com.google.gerrit.common.PageLinks;
import com.google.gerrit.common.data.AccountProjectWatchInfo;
import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwt.core.client.JsArray;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.KeyCodes;
@@ -36,8 +36,6 @@ import com.google.gwt.user.client.ui.Grid;
import com.google.gwt.user.client.ui.HTMLTable.CellFormatter;
import com.google.gwt.user.client.ui.HorizontalPanel;
import java.util.List;
public class MyWatchedProjectsScreen extends SettingsScreen {
private Button addNew;
private RemoteSuggestBox nameBox;
@@ -188,35 +186,40 @@ public class MyWatchedProjectsScreen extends SettingsScreen {
nameBox.setEnabled(false);
filterTxt.setEnabled(false);
Util.ACCOUNT_SVC.addProjectWatch(projectName, filter,
new GerritCallback<AccountProjectWatchInfo>() {
final ProjectWatchInfo projectWatchInfo = JavaScriptObject
.createObject().cast();
projectWatchInfo.project(projectName);
projectWatchInfo.filter(filterTxt.getText());
AccountApi.updateWatchedProject("self", projectWatchInfo,
new GerritCallback<JsArray<ProjectWatchInfo>>() {
@Override
public void onSuccess(final AccountProjectWatchInfo result) {
public void onSuccess(JsArray<ProjectWatchInfo> watchedProjects) {
addNew.setEnabled(true);
nameBox.setEnabled(true);
filterTxt.setEnabled(true);
nameBox.setText("");
watchesTab.insertWatch(result);
watchesTab.insertWatch(projectWatchInfo);
}
@Override
public void onFailure(final Throwable caught) {
public void onFailure(Throwable caught) {
addNew.setEnabled(true);
nameBox.setEnabled(true);
filterTxt.setEnabled(true);
super.onFailure(caught);
}
});
}
protected void populateWatches() {
Util.ACCOUNT_SVC.myProjectWatch(
new ScreenLoadCallback<List<AccountProjectWatchInfo>>(this) {
AccountApi.getWatchedProjects("self",
new GerritCallback<JsArray<ProjectWatchInfo>>() {
@Override
public void preDisplay(final List<AccountProjectWatchInfo> result) {
watchesTab.display(result);
public void onSuccess(JsArray<ProjectWatchInfo> watchedProjects) {
display();
watchesTab.display(watchedProjects);
}
});
}

View File

@@ -16,23 +16,22 @@ package com.google.gerrit.client.account;
import com.google.gerrit.client.Gerrit;
import com.google.gerrit.client.rpc.GerritCallback;
import com.google.gerrit.client.rpc.Natives;
import com.google.gerrit.client.ui.FancyFlexTable;
import com.google.gerrit.client.ui.ProjectLink;
import com.google.gerrit.common.data.AccountProjectWatchInfo;
import com.google.gerrit.reviewdb.client.AccountProjectWatch;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gwt.core.client.JsArray;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.ui.CheckBox;
import com.google.gwt.user.client.ui.FlexTable.FlexCellFormatter;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwtjsonrpc.common.VoidResult;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
public class MyWatchesTable extends FancyFlexTable<AccountProjectWatchInfo> {
public class MyWatchesTable extends FancyFlexTable<ProjectWatchInfo> {
public MyWatchesTable() {
table.setWidth("");
@@ -63,22 +62,22 @@ public class MyWatchesTable extends FancyFlexTable<AccountProjectWatchInfo> {
}
public void deleteChecked() {
final Set<AccountProjectWatch.Key> ids = getCheckedIds();
if (!ids.isEmpty()) {
Util.ACCOUNT_SVC.deleteProjectWatches(ids,
new GerritCallback<VoidResult>() {
final Set<ProjectWatchInfo> infos = getCheckedProjectWatchInfos();
if (!infos.isEmpty()) {
AccountApi.deleteWatchedProjects("self", infos,
new GerritCallback<JsArray<ProjectWatchInfo>>() {
@Override
public void onSuccess(final VoidResult result) {
remove(ids);
public void onSuccess(JsArray<ProjectWatchInfo> watchedProjects) {
remove(infos);
}
});
}
}
protected void remove(Set<AccountProjectWatch.Key> ids) {
protected void remove(Set<ProjectWatchInfo> infos) {
for (int row = 1; row < table.getRowCount();) {
final AccountProjectWatchInfo k = getRowItem(row);
if (k != null && ids.contains(k.getWatch().getKey())) {
final ProjectWatchInfo k = getRowItem(row);
if (k != null && infos.contains(k)) {
table.removeRow(row);
} else {
row++;
@@ -86,23 +85,23 @@ public class MyWatchesTable extends FancyFlexTable<AccountProjectWatchInfo> {
}
}
protected Set<AccountProjectWatch.Key> getCheckedIds() {
final Set<AccountProjectWatch.Key> ids = new HashSet<>();
protected Set<ProjectWatchInfo> getCheckedProjectWatchInfos() {
final Set<ProjectWatchInfo> infos = new HashSet<>();
for (int row = 1; row < table.getRowCount(); row++) {
final AccountProjectWatchInfo k = getRowItem(row);
final ProjectWatchInfo k = getRowItem(row);
if (k != null && ((CheckBox) table.getWidget(row, 1)).getValue()) {
ids.add(k.getWatch().getKey());
infos.add(k);
}
}
return ids;
return infos;
}
public void insertWatch(final AccountProjectWatchInfo k) {
final String newName = k.getProject().getName();
public void insertWatch(final ProjectWatchInfo k) {
final String newName = k.project();
int row = 1;
for (; row < table.getRowCount(); row++) {
final AccountProjectWatchInfo i = getRowItem(row);
if (i != null && i.getProject().getName().compareTo(newName) >= 0) {
final ProjectWatchInfo i = getRowItem(row);
if (i != null && i.project().compareTo(newName) >= 0) {
break;
}
}
@@ -112,24 +111,25 @@ public class MyWatchesTable extends FancyFlexTable<AccountProjectWatchInfo> {
populate(row, k);
}
public void display(final List<AccountProjectWatchInfo> result) {
public void display(final JsArray<ProjectWatchInfo> result) {
while (2 < table.getRowCount()) {
table.removeRow(table.getRowCount() - 1);
}
for (final AccountProjectWatchInfo k : result) {
for (ProjectWatchInfo info : Natives.asList(result)) {
final int row = table.getRowCount();
table.insertRow(row);
applyDataRowStyle(row);
populate(row, k);
populate(row, info);
}
}
protected void populate(final int row, final AccountProjectWatchInfo info) {
protected void populate(final int row, final ProjectWatchInfo info) {
final FlowPanel fp = new FlowPanel();
fp.add(new ProjectLink(info.getProject().getNameKey()));
if (info.getWatch().getFilter() != null) {
Label filter = new Label(info.getWatch().getFilter());
fp.add(new ProjectLink(info.project(),
new Project.NameKey(info.project())));
if (info.filter() != null) {
Label filter = new Label(info.filter());
filter.setStyleName(Gerrit.RESOURCES.css().watchedProjectFilter());
fp.add(filter);
}
@@ -137,11 +137,11 @@ public class MyWatchesTable extends FancyFlexTable<AccountProjectWatchInfo> {
table.setWidget(row, 1, new CheckBox());
table.setWidget(row, 2, fp);
addNotifyButton(AccountProjectWatch.NotifyType.NEW_CHANGES, info, row, 3);
addNotifyButton(AccountProjectWatch.NotifyType.NEW_PATCHSETS, info, row, 4);
addNotifyButton(AccountProjectWatch.NotifyType.ALL_COMMENTS, info, row, 5);
addNotifyButton(AccountProjectWatch.NotifyType.SUBMITTED_CHANGES, info, row, 6);
addNotifyButton(AccountProjectWatch.NotifyType.ABANDONED_CHANGES, info, row, 7);
addNotifyButton(ProjectWatchInfo.Type.NEW_CHANGES, info, row, 3);
addNotifyButton(ProjectWatchInfo.Type.NEW_PATCHSETS, info, row, 4);
addNotifyButton(ProjectWatchInfo.Type.ALL_COMMENTS, info, row, 5);
addNotifyButton(ProjectWatchInfo.Type.SUBMITTED_CHANGES, info, row, 6);
addNotifyButton(ProjectWatchInfo.Type.ABANDONED_CHANGES, info, row, 7);
final FlexCellFormatter fmt = table.getFlexCellFormatter();
fmt.addStyleName(row, 1, Gerrit.RESOURCES.css().iconCell());
@@ -155,27 +155,28 @@ public class MyWatchesTable extends FancyFlexTable<AccountProjectWatchInfo> {
setRowItem(row, info);
}
protected void addNotifyButton(final AccountProjectWatch.NotifyType type,
final AccountProjectWatchInfo info, final int row, final int col) {
protected void addNotifyButton(final ProjectWatchInfo.Type type,
final ProjectWatchInfo info, final int row, final int col) {
final CheckBox cbox = new CheckBox();
cbox.addClickHandler(new ClickHandler() {
@Override
public void onClick(final ClickEvent event) {
final boolean oldVal = info.getWatch().isNotify(type);
info.getWatch().setNotify(type, cbox.getValue());
final Boolean oldVal = info.notify(type);
info.notify(type, cbox.getValue());
cbox.setEnabled(false);
Util.ACCOUNT_SVC.updateProjectWatch(info.getWatch(),
new GerritCallback<VoidResult>() {
AccountApi.updateWatchedProject("self", info,
new GerritCallback<JsArray<ProjectWatchInfo>>() {
@Override
public void onSuccess(final VoidResult result) {
public void onSuccess(JsArray<ProjectWatchInfo> watchedProjects) {
cbox.setEnabled(true);
}
@Override
public void onFailure(final Throwable caught) {
public void onFailure(Throwable caught) {
cbox.setEnabled(true);
info.getWatch().setNotify(type, oldVal);
info.notify(type, oldVal);
cbox.setValue(oldVal);
super.onFailure(caught);
}
@@ -183,7 +184,7 @@ public class MyWatchesTable extends FancyFlexTable<AccountProjectWatchInfo> {
}
});
cbox.setValue(info.getWatch().isNotify(type));
cbox.setValue(info.notify(type));
table.setWidget(row, col, cbox);
}
}

View File

@@ -0,0 +1,79 @@
// Copyright (C) 2016 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.
package com.google.gerrit.client.account;
import com.google.gwt.core.client.JavaScriptObject;
public class ProjectWatchInfo extends JavaScriptObject {
public enum Type {
NEW_CHANGES,
NEW_PATCHSETS,
ALL_COMMENTS,
SUBMITTED_CHANGES,
ABANDONED_CHANGES
}
public final native String project() /*-{ return this.project; }-*/;
public final native String filter() /*-{ return this.filter; }-*/;
public final native void project(String s) /*-{ this.project = s; }-*/;
public final native void filter(String s) /*-{ this.filter = s; }-*/;
public final void notify(ProjectWatchInfo.Type t, Boolean b) {
if (t == ProjectWatchInfo.Type.NEW_CHANGES) {
notifyNewChanges(b.booleanValue());
} else if (t == Type.NEW_PATCHSETS) {
notifyNewPatchSets(b.booleanValue());
} else if (t == Type.ALL_COMMENTS) {
notifyAllComments(b.booleanValue());
} else if (t == Type.SUBMITTED_CHANGES) {
notifySubmittedChanges(b.booleanValue());
} else if (t == Type.ABANDONED_CHANGES) {
notifyAbandonedChanges(b.booleanValue());
}
}
public final Boolean notify(ProjectWatchInfo.Type t) {
boolean b = false;
if (t == ProjectWatchInfo.Type.NEW_CHANGES) {
b = notifyNewChanges();
} else if (t == Type.NEW_PATCHSETS) {
b = notifyNewPatchSets();
} else if (t == Type.ALL_COMMENTS) {
b = notifyAllComments();
} else if (t == Type.SUBMITTED_CHANGES) {
b = notifySubmittedChanges();
} else if (t == Type.ABANDONED_CHANGES) {
b = notifyAbandonedChanges();
}
return Boolean.valueOf(b);
}
private native boolean notifyNewChanges() /*-{ return this['notify_new_changes'] ? true : false; }-*/;
private native boolean notifyNewPatchSets() /*-{ return this['notify_new_patch_sets'] ? true : false; }-*/;
private native boolean notifyAllComments() /*-{ return this['notify_all_comments'] ? true : false; }-*/;
private native boolean notifySubmittedChanges() /*-{ return this['notify_submitted_changes'] ? true : false; }-*/;
private native boolean notifyAbandonedChanges() /*-{ return this['notify_abandoned_changes'] ? true : false; }-*/;
private native void notifyNewChanges(boolean b) /*-{ this['notify_new_changes'] = b ? true : null; }-*/;
private native void notifyNewPatchSets(boolean b) /*-{ this['notify_new_patch_sets'] = b ? true : null; }-*/;
private native void notifyAllComments(boolean b) /*-{ this['notify_all_comments'] = b ? true : null; }-*/;
private native void notifySubmittedChanges(boolean b) /*-{ this['notify_submitted_changes'] = b ? true : null; }-*/;
private native void notifyAbandonedChanges(boolean b) /*-{ this['notify_abandoned_changes'] = b ? true : null; }-*/;
protected ProjectWatchInfo() {
}
}