Add project watch support and cleanup SSH key management UI
We now import the "watched projects" from Gerrit 1, the list of projects the user wants to know if there are new changes in. Signed-off-by: Shawn O. Pearce <sop@google.com>
This commit is contained in:
@@ -28,6 +28,8 @@
|
||||
class='com.google.gerrit.server.ChangeListServiceSrv'/>
|
||||
<servlet path='/rpc/PatchDetailService'
|
||||
class='com.google.gerrit.server.PatchDetailServiceSrv'/>
|
||||
<servlet path='/rpc/SuggestService'
|
||||
class='com.google.gerrit.server.SuggestServiceSrv'/>
|
||||
<servlet path='/rpc/SystemInfoService'
|
||||
class='com.google.gerrit.server.SystemInfoServiceSrv'/>
|
||||
</module>
|
||||
|
@@ -20,7 +20,19 @@ import com.google.gwt.user.client.ui.Label;
|
||||
import com.google.gwt.user.client.ui.Panel;
|
||||
import com.google.gwtjsonrpc.client.RpcStatusListener;
|
||||
|
||||
class RpcStatus implements RpcStatusListener {
|
||||
public class RpcStatus implements RpcStatusListener {
|
||||
private static int hideDepth;
|
||||
|
||||
/** Execute code, hiding the RPCs they execute from being shown visually. */
|
||||
public static void hide(final Runnable run) {
|
||||
try {
|
||||
hideDepth++;
|
||||
run.run();
|
||||
} finally {
|
||||
hideDepth--;
|
||||
}
|
||||
}
|
||||
|
||||
private final Label loading;
|
||||
private int activeCalls;
|
||||
|
||||
@@ -39,7 +51,9 @@ class RpcStatus implements RpcStatusListener {
|
||||
|
||||
public void onCallStart() {
|
||||
if (++activeCalls == 1) {
|
||||
loading.setVisible(true);
|
||||
if (hideDepth == 0) {
|
||||
loading.setVisible(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -38,4 +38,9 @@ public interface AccountConstants extends Constants {
|
||||
String sshKeyStored();
|
||||
|
||||
String addSshKeyPanelHeader();
|
||||
String addSshKeyHelp();
|
||||
|
||||
String watchedProjects();
|
||||
String buttonWatchProject();
|
||||
String defaultProjectName();
|
||||
}
|
||||
|
@@ -18,4 +18,9 @@ sshKeyComment = Comment
|
||||
sshKeyLastUsed = Last Used
|
||||
sshKeyStored = Stored
|
||||
|
||||
addSshKeyPanelHeader = Add SSH Key
|
||||
addSshKeyPanelHeader = Add SSH Public Key
|
||||
addSshKeyHelp = (<a href="http://github.com/guides/providing-your-ssh-key" target="_blank">GitHub's Guide to SSH Keys</a>)
|
||||
|
||||
watchedProjects = Watched Projects
|
||||
buttonWatchProject = Watch
|
||||
defaultProjectName = Project Name
|
||||
|
@@ -0,0 +1,39 @@
|
||||
// Copyright 2008 Google Inc.
|
||||
//
|
||||
// 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.gerrit.client.reviewdb.AccountProjectWatch;
|
||||
import com.google.gerrit.client.reviewdb.Project;
|
||||
|
||||
public final class AccountProjectWatchInfo {
|
||||
protected AccountProjectWatch watch;
|
||||
protected Project project;
|
||||
|
||||
protected AccountProjectWatchInfo() {
|
||||
}
|
||||
|
||||
public AccountProjectWatchInfo(final AccountProjectWatch w, final Project p) {
|
||||
watch = w;
|
||||
project = p;
|
||||
}
|
||||
|
||||
public AccountProjectWatch getWatch() {
|
||||
return watch;
|
||||
}
|
||||
|
||||
public Project getProject() {
|
||||
return project;
|
||||
}
|
||||
}
|
@@ -15,15 +15,30 @@
|
||||
package com.google.gerrit.client.account;
|
||||
|
||||
import com.google.gerrit.client.reviewdb.Account;
|
||||
import com.google.gerrit.client.reviewdb.AccountProjectWatch;
|
||||
import com.google.gerrit.client.rpc.SignInRequired;
|
||||
import com.google.gwt.user.client.rpc.AsyncCallback;
|
||||
import com.google.gwtjsonrpc.client.RemoteJsonService;
|
||||
import com.google.gwtjsonrpc.client.VoidResult;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
public interface AccountService extends RemoteJsonService {
|
||||
@SignInRequired
|
||||
void myAccount(AsyncCallback<Account> callback);
|
||||
|
||||
@SignInRequired
|
||||
void changeDefaultContext(short newSetting, AsyncCallback<VoidResult> callback);
|
||||
|
||||
@SignInRequired
|
||||
void myProjectWatch(AsyncCallback<List<AccountProjectWatchInfo>> callback);
|
||||
|
||||
@SignInRequired
|
||||
void addProjectWatch(String projectName,
|
||||
AsyncCallback<AccountProjectWatchInfo> callback);
|
||||
|
||||
@SignInRequired
|
||||
void deleteProjectWatches(Set<AccountProjectWatch.Key> keys,
|
||||
AsyncCallback<VoidResult> callback);
|
||||
}
|
||||
|
@@ -15,15 +15,23 @@
|
||||
package com.google.gerrit.client.account;
|
||||
|
||||
import com.google.gerrit.client.reviewdb.Account;
|
||||
import com.google.gerrit.client.reviewdb.AccountProjectWatch;
|
||||
import com.google.gerrit.client.reviewdb.Project;
|
||||
import com.google.gerrit.client.reviewdb.ReviewDb;
|
||||
import com.google.gerrit.client.rpc.BaseServiceImplementation;
|
||||
import com.google.gerrit.client.rpc.NoSuchEntityException;
|
||||
import com.google.gerrit.client.rpc.RpcUtil;
|
||||
import com.google.gwt.user.client.rpc.AsyncCallback;
|
||||
import com.google.gwtjsonrpc.client.VoidResult;
|
||||
import com.google.gwtorm.client.OrmException;
|
||||
import com.google.gwtorm.client.SchemaFactory;
|
||||
import com.google.gwtorm.client.Transaction;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
public class AccountServiceImpl extends BaseServiceImplementation implements
|
||||
AccountService {
|
||||
@@ -50,4 +58,74 @@ public class AccountServiceImpl extends BaseServiceImplementation implements
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void myProjectWatch(
|
||||
final AsyncCallback<List<AccountProjectWatchInfo>> callback) {
|
||||
run(callback, new Action<List<AccountProjectWatchInfo>>() {
|
||||
public List<AccountProjectWatchInfo> run(ReviewDb db) throws OrmException {
|
||||
final List<AccountProjectWatchInfo> r =
|
||||
new ArrayList<AccountProjectWatchInfo>();
|
||||
|
||||
for (final AccountProjectWatch w : db.accountProjectWatches()
|
||||
.byAccount(RpcUtil.getAccountId()).toList()) {
|
||||
final Project p = db.projects().get(w.getProjectId());
|
||||
if (p == null) {
|
||||
db.accountProjectWatches().delete(Collections.singleton(w));
|
||||
continue;
|
||||
}
|
||||
r.add(new AccountProjectWatchInfo(w, p));
|
||||
}
|
||||
Collections.sort(r, new Comparator<AccountProjectWatchInfo>() {
|
||||
public int compare(final AccountProjectWatchInfo a,
|
||||
final AccountProjectWatchInfo b) {
|
||||
return a.getProject().getName().compareTo(b.getProject().getName());
|
||||
}
|
||||
});
|
||||
return r;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void addProjectWatch(final String projectName,
|
||||
final AsyncCallback<AccountProjectWatchInfo> callback) {
|
||||
run(callback, new Action<AccountProjectWatchInfo>() {
|
||||
public AccountProjectWatchInfo run(ReviewDb db) throws OrmException,
|
||||
Failure {
|
||||
final Project project =
|
||||
db.projects().get(new Project.NameKey(projectName));
|
||||
if (project == null) {
|
||||
throw new Failure(new NoSuchEntityException());
|
||||
}
|
||||
|
||||
final AccountProjectWatch watch =
|
||||
new AccountProjectWatch(new AccountProjectWatch.Key(RpcUtil
|
||||
.getAccountId(), project.getId()));
|
||||
db.accountProjectWatches().insert(Collections.singleton(watch));
|
||||
return new AccountProjectWatchInfo(watch, project);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void deleteProjectWatches(final Set<AccountProjectWatch.Key> keys,
|
||||
final AsyncCallback<VoidResult> callback) {
|
||||
run(callback, new Action<VoidResult>() {
|
||||
public VoidResult run(final ReviewDb db) throws OrmException, Failure {
|
||||
final Account.Id me = RpcUtil.getAccountId();
|
||||
for (final AccountProjectWatch.Key keyId : keys) {
|
||||
if (!me.equals(keyId.getParentKey()))
|
||||
throw new Failure(new NoSuchEntityException());
|
||||
}
|
||||
|
||||
final List<AccountProjectWatch> k =
|
||||
db.accountProjectWatches().get(keys).toList();
|
||||
if (!k.isEmpty()) {
|
||||
final Transaction txn = db.beginTransaction();
|
||||
db.accountProjectWatches().delete(k, txn);
|
||||
txn.commit();
|
||||
}
|
||||
|
||||
return VoidResult.INSTANCE;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@@ -20,6 +20,7 @@ import com.google.gerrit.client.Gerrit;
|
||||
import com.google.gerrit.client.reviewdb.Account;
|
||||
import com.google.gerrit.client.rpc.GerritCallback;
|
||||
import com.google.gerrit.client.ui.AccountScreen;
|
||||
import com.google.gerrit.client.ui.LazyTabChild;
|
||||
import com.google.gwt.i18n.client.LocaleInfo;
|
||||
import com.google.gwt.user.client.ui.FlowPanel;
|
||||
import com.google.gwt.user.client.ui.Grid;
|
||||
@@ -36,7 +37,6 @@ public class AccountSettings extends AccountScreen {
|
||||
|
||||
private PreferencePanel prefsPanel;
|
||||
private Panel agreementsPanel;
|
||||
private SshKeyPanel keysPanel;
|
||||
|
||||
public AccountSettings() {
|
||||
super(Util.C.accountSettingsHeading());
|
||||
@@ -64,15 +64,18 @@ public class AccountSettings extends AccountScreen {
|
||||
fmt.addStyleName(2, 0, "bottomheader");
|
||||
|
||||
prefsPanel = new PreferencePanel();
|
||||
keysPanel = new SshKeyPanel();
|
||||
|
||||
agreementsPanel = new FlowPanel();
|
||||
agreementsPanel.add(new Label("Not Implemented"));
|
||||
|
||||
tabs = new TabPanel();
|
||||
tabs.setWidth("100%");
|
||||
tabs.setWidth("98%");
|
||||
tabs.add(prefsPanel, Util.C.tabPreferences());
|
||||
tabs.add(keysPanel, Util.C.tabSshKeys());
|
||||
tabs.add(new LazyTabChild<SshKeyPanel>() {
|
||||
@Override
|
||||
protected SshKeyPanel create() {
|
||||
return new SshKeyPanel();
|
||||
}
|
||||
}, Util.C.tabSshKeys());
|
||||
tabs.add(agreementsPanel, Util.C.tabAgreements());
|
||||
|
||||
add(tabs);
|
||||
|
@@ -22,15 +22,17 @@ import com.google.gwt.user.client.ui.ChangeListener;
|
||||
import com.google.gwt.user.client.ui.Composite;
|
||||
import com.google.gwt.user.client.ui.FlowPanel;
|
||||
import com.google.gwt.user.client.ui.Grid;
|
||||
import com.google.gwt.user.client.ui.Label;
|
||||
import com.google.gwt.user.client.ui.ListBox;
|
||||
import com.google.gwt.user.client.ui.Widget;
|
||||
import com.google.gwtjsonrpc.client.VoidResult;
|
||||
|
||||
public class PreferencePanel extends Composite {
|
||||
class PreferencePanel extends Composite {
|
||||
private ListBox defaultContext;
|
||||
private short oldDefaultContext;
|
||||
private ProjectWatchPanel watchPanel;
|
||||
|
||||
public PreferencePanel() {
|
||||
PreferencePanel() {
|
||||
final FlowPanel body = new FlowPanel();
|
||||
|
||||
defaultContext = new ListBox();
|
||||
@@ -80,6 +82,19 @@ public class PreferencePanel extends Composite {
|
||||
|
||||
body.add(formGrid);
|
||||
|
||||
{
|
||||
final FlowPanel fp = new FlowPanel();
|
||||
fp.setStyleName("gerrit-WatchedProjectPanel");
|
||||
|
||||
final Label hdr = new Label(Util.C.watchedProjects());
|
||||
hdr.setStyleName("gerrit-SmallHeading");
|
||||
fp.add(hdr);
|
||||
|
||||
watchPanel = new ProjectWatchPanel();
|
||||
fp.add(watchPanel);
|
||||
body.add(fp);
|
||||
}
|
||||
|
||||
initWidget(body);
|
||||
}
|
||||
|
||||
|
@@ -0,0 +1,264 @@
|
||||
// Copyright 2008 Google Inc.
|
||||
//
|
||||
// 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.gerrit.client.reviewdb.AccountProjectWatch;
|
||||
import com.google.gerrit.client.rpc.GerritCallback;
|
||||
import com.google.gerrit.client.ui.FancyFlexTable;
|
||||
import com.google.gerrit.client.ui.ProjectNameSuggestOracle;
|
||||
import com.google.gwt.user.client.ui.Button;
|
||||
import com.google.gwt.user.client.ui.CheckBox;
|
||||
import com.google.gwt.user.client.ui.ClickListener;
|
||||
import com.google.gwt.user.client.ui.Composite;
|
||||
import com.google.gwt.user.client.ui.FlowPanel;
|
||||
import com.google.gwt.user.client.ui.FocusListenerAdapter;
|
||||
import com.google.gwt.user.client.ui.SourcesTableEvents;
|
||||
import com.google.gwt.user.client.ui.SuggestBox;
|
||||
import com.google.gwt.user.client.ui.TableListener;
|
||||
import com.google.gwt.user.client.ui.TextBox;
|
||||
import com.google.gwt.user.client.ui.Widget;
|
||||
import com.google.gwt.user.client.ui.FlexTable.FlexCellFormatter;
|
||||
import com.google.gwtjsonrpc.client.VoidResult;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
|
||||
class ProjectWatchPanel extends Composite {
|
||||
private WatchTable watches;
|
||||
|
||||
private Button addNew;
|
||||
private SuggestBox nameTxt;
|
||||
private Button delSel;
|
||||
|
||||
ProjectWatchPanel() {
|
||||
final FlowPanel body = new FlowPanel();
|
||||
|
||||
{
|
||||
final FlowPanel fp = new FlowPanel();
|
||||
fp.setStyleName("gerrit-ProjectWatchPanel-AddPanel");
|
||||
|
||||
final TextBox box = new TextBox();
|
||||
nameTxt = new SuggestBox(new ProjectNameSuggestOracle(), box);
|
||||
box.setVisibleLength(50);
|
||||
box.setText(Util.C.defaultProjectName());
|
||||
box.addStyleName("gerrit-InputFieldTypeHint");
|
||||
box.addFocusListener(new FocusListenerAdapter() {
|
||||
@Override
|
||||
public void onFocus(Widget sender) {
|
||||
if (Util.C.defaultProjectName().equals(box.getText())) {
|
||||
box.setText("");
|
||||
box.removeStyleName("gerrit-InputFieldTypeHint");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLostFocus(Widget sender) {
|
||||
if ("".equals(box.getText())) {
|
||||
box.setText(Util.C.defaultProjectName());
|
||||
box.addStyleName("gerrit-InputFieldTypeHint");
|
||||
}
|
||||
}
|
||||
});
|
||||
fp.add(nameTxt);
|
||||
|
||||
addNew = new Button(Util.C.buttonWatchProject());
|
||||
addNew.addClickListener(new ClickListener() {
|
||||
public void onClick(final Widget sender) {
|
||||
doAddNew();
|
||||
}
|
||||
});
|
||||
fp.add(addNew);
|
||||
body.add(fp);
|
||||
}
|
||||
|
||||
watches = new WatchTable();
|
||||
body.add(watches);
|
||||
{
|
||||
final FlowPanel fp = new FlowPanel();
|
||||
delSel = new Button(Util.C.buttonDeleteSshKey());
|
||||
delSel.addClickListener(new ClickListener() {
|
||||
public void onClick(final Widget sender) {
|
||||
watches.deleteChecked();
|
||||
}
|
||||
});
|
||||
fp.add(delSel);
|
||||
body.add(fp);
|
||||
}
|
||||
|
||||
initWidget(body);
|
||||
}
|
||||
|
||||
void doAddNew() {
|
||||
final String projectName = nameTxt.getText();
|
||||
if (projectName == null || projectName.length() == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (watches.moveToExistingProject(projectName)) {
|
||||
nameTxt.setText("");
|
||||
return;
|
||||
}
|
||||
|
||||
addNew.setEnabled(false);
|
||||
Util.ACCOUNT_SVC.addProjectWatch(projectName,
|
||||
new GerritCallback<AccountProjectWatchInfo>() {
|
||||
public void onSuccess(final AccountProjectWatchInfo result) {
|
||||
addNew.setEnabled(true);
|
||||
nameTxt.setText("");
|
||||
watches.insertWatch(result);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(final Throwable caught) {
|
||||
addNew.setEnabled(true);
|
||||
super.onFailure(caught);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoad() {
|
||||
super.onLoad();
|
||||
Util.ACCOUNT_SVC
|
||||
.myProjectWatch(new GerritCallback<List<AccountProjectWatchInfo>>() {
|
||||
public void onSuccess(final List<AccountProjectWatchInfo> result) {
|
||||
watches.display(result);
|
||||
watches.finishDisplay(true);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private class WatchTable extends FancyFlexTable<AccountProjectWatchInfo> {
|
||||
WatchTable() {
|
||||
table.setText(0, 2, com.google.gerrit.client.changes.Util.C
|
||||
.changeTableColumnProject());
|
||||
table.addTableListener(new TableListener() {
|
||||
public void onCellClicked(SourcesTableEvents sender, int row, int cell) {
|
||||
if (cell != 1 && getRowItem(row) != null) {
|
||||
movePointerTo(row);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
final FlexCellFormatter fmt = table.getFlexCellFormatter();
|
||||
fmt.addStyleName(0, 1, S_ICON_HEADER);
|
||||
fmt.addStyleName(0, 2, S_DATA_HEADER);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Object getRowItemKey(final AccountProjectWatchInfo item) {
|
||||
return item.getWatch().getKey();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean onKeyPress(final char keyCode, final int modifiers) {
|
||||
if (super.onKeyPress(keyCode, modifiers)) {
|
||||
return true;
|
||||
}
|
||||
if (modifiers == 0) {
|
||||
switch (keyCode) {
|
||||
case 's':
|
||||
case 'c':
|
||||
toggleCurrentRow();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onOpenItem(final AccountProjectWatchInfo item) {
|
||||
toggleCurrentRow();
|
||||
}
|
||||
|
||||
private void toggleCurrentRow() {
|
||||
final CheckBox cb = (CheckBox) table.getWidget(getCurrentRow(), 1);
|
||||
cb.setChecked(!cb.isChecked());
|
||||
}
|
||||
|
||||
void deleteChecked() {
|
||||
final HashSet<AccountProjectWatch.Key> ids =
|
||||
new HashSet<AccountProjectWatch.Key>();
|
||||
for (int row = 1; row < table.getRowCount(); row++) {
|
||||
final AccountProjectWatchInfo k = getRowItem(row);
|
||||
if (k != null && ((CheckBox) table.getWidget(row, 1)).isChecked()) {
|
||||
ids.add(k.getWatch().getKey());
|
||||
}
|
||||
}
|
||||
if (!ids.isEmpty()) {
|
||||
Util.ACCOUNT_SVC.deleteProjectWatches(ids,
|
||||
new GerritCallback<VoidResult>() {
|
||||
public void onSuccess(final VoidResult result) {
|
||||
for (int row = 1; row < table.getRowCount();) {
|
||||
final AccountProjectWatchInfo k = getRowItem(row);
|
||||
if (k != null && ids.contains(k.getWatch().getKey())) {
|
||||
table.removeRow(row);
|
||||
} else {
|
||||
row++;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
boolean moveToExistingProject(final String projectName) {
|
||||
for (int row = 1; row < table.getRowCount(); row++) {
|
||||
final AccountProjectWatchInfo i = getRowItem(row);
|
||||
if (i != null && i.getProject().getName().equals(projectName)) {
|
||||
movePointerTo(row);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void insertWatch(final AccountProjectWatchInfo k) {
|
||||
final String newName = k.getProject().getName();
|
||||
int row = 1;
|
||||
for (; row < table.getRowCount(); row++) {
|
||||
final AccountProjectWatchInfo i = getRowItem(row);
|
||||
if (i != null && i.getProject().getName().compareTo(newName) >= 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
table.insertRow(row);
|
||||
populate(row, k);
|
||||
}
|
||||
|
||||
void display(final List<AccountProjectWatchInfo> result) {
|
||||
while (1 < table.getRowCount())
|
||||
table.removeRow(table.getRowCount() - 1);
|
||||
|
||||
for (final AccountProjectWatchInfo k : result) {
|
||||
final int row = table.getRowCount();
|
||||
table.insertRow(row);
|
||||
populate(row, k);
|
||||
}
|
||||
}
|
||||
|
||||
void populate(final int row, final AccountProjectWatchInfo k) {
|
||||
table.setWidget(row, 1, new CheckBox());
|
||||
table.setText(row, 2, k.getProject().getName());
|
||||
|
||||
final FlexCellFormatter fmt = table.getFlexCellFormatter();
|
||||
fmt.addStyleName(row, 1, S_ICON_CELL);
|
||||
fmt.addStyleName(row, 2, S_DATA_CELL);
|
||||
|
||||
setRowItem(row, k);
|
||||
}
|
||||
}
|
||||
}
|
@@ -24,6 +24,7 @@ import com.google.gwt.user.client.ui.CheckBox;
|
||||
import com.google.gwt.user.client.ui.ClickListener;
|
||||
import com.google.gwt.user.client.ui.Composite;
|
||||
import com.google.gwt.user.client.ui.FlowPanel;
|
||||
import com.google.gwt.user.client.ui.HTML;
|
||||
import com.google.gwt.user.client.ui.Label;
|
||||
import com.google.gwt.user.client.ui.SourcesTableEvents;
|
||||
import com.google.gwt.user.client.ui.TableListener;
|
||||
@@ -36,14 +37,14 @@ import com.google.gwtjsonrpc.client.VoidResult;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
|
||||
public class SshKeyPanel extends Composite {
|
||||
class SshKeyPanel extends Composite {
|
||||
private SshKeyTable keys;
|
||||
|
||||
private Button addNew;
|
||||
private TextArea addTxt;
|
||||
private Button delSel;
|
||||
|
||||
public SshKeyPanel() {
|
||||
SshKeyPanel() {
|
||||
final FlowPanel body = new FlowPanel();
|
||||
|
||||
keys = new SshKeyTable();
|
||||
@@ -63,7 +64,10 @@ public class SshKeyPanel extends Composite {
|
||||
{
|
||||
final VerticalPanel fp = new VerticalPanel();
|
||||
fp.setStyleName("gerrit-AddSshKeyPanel");
|
||||
fp.add(new Label(Util.C.addSshKeyPanelHeader()));
|
||||
final Label hdr = new Label(Util.C.addSshKeyPanelHeader());
|
||||
hdr.setStyleName("gerrit-SmallHeading");
|
||||
fp.add(hdr);
|
||||
fp.add(new HTML(Util.C.addSshKeyHelp()));
|
||||
|
||||
addTxt = new TextArea();
|
||||
addTxt.setVisibleLines(12);
|
||||
@@ -104,14 +108,8 @@ public class SshKeyPanel extends Composite {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setVisible(final boolean visible) {
|
||||
if (!isVisible()) {
|
||||
update();
|
||||
}
|
||||
super.setVisible(visible);
|
||||
}
|
||||
|
||||
public void update() {
|
||||
public void onLoad() {
|
||||
super.onLoad();
|
||||
Util.ACCOUNT_SEC.mySshKeys(new GerritCallback<List<AccountSshKey>>() {
|
||||
public void onSuccess(final List<AccountSshKey> result) {
|
||||
keys.display(result);
|
||||
@@ -230,6 +228,8 @@ public class SshKeyPanel extends Composite {
|
||||
for (int c = 3; c <= 7; c++) {
|
||||
fmt.addStyleName(row, c, S_DATA_CELL);
|
||||
}
|
||||
fmt.addStyleName(row, 6, "C_LAST_UPDATE");
|
||||
fmt.addStyleName(row, 7, "C_LAST_UPDATE");
|
||||
|
||||
setRowItem(row, k);
|
||||
}
|
||||
|
@@ -0,0 +1,71 @@
|
||||
// Copyright 2008 Google Inc.
|
||||
//
|
||||
// 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.reviewdb;
|
||||
|
||||
import com.google.gwtorm.client.Column;
|
||||
import com.google.gwtorm.client.CompoundKey;
|
||||
|
||||
/** An {@link Account} interested in a {@link Project}. */
|
||||
public final class AccountProjectWatch {
|
||||
public static class Key extends CompoundKey<Account.Id> {
|
||||
@Column
|
||||
protected Account.Id accountId;
|
||||
|
||||
@Column
|
||||
protected Project.Id projectId;
|
||||
|
||||
protected Key() {
|
||||
accountId = new Account.Id();
|
||||
projectId = new Project.Id();
|
||||
}
|
||||
|
||||
public Key(final Account.Id a, final Project.Id g) {
|
||||
accountId = a;
|
||||
projectId = g;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Account.Id getParentKey() {
|
||||
return accountId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public com.google.gwtorm.client.Key<?>[] members() {
|
||||
return new com.google.gwtorm.client.Key<?>[] {projectId};
|
||||
}
|
||||
}
|
||||
|
||||
@Column(name = Column.NONE)
|
||||
protected Key key;
|
||||
|
||||
protected AccountProjectWatch() {
|
||||
}
|
||||
|
||||
public AccountProjectWatch(final AccountProjectWatch.Key k) {
|
||||
key = k;
|
||||
}
|
||||
|
||||
public AccountProjectWatch.Key getKey() {
|
||||
return key;
|
||||
}
|
||||
|
||||
public Account.Id getAccountId() {
|
||||
return key.accountId;
|
||||
}
|
||||
|
||||
public Project.Id getProjectId() {
|
||||
return key.projectId;
|
||||
}
|
||||
}
|
@@ -0,0 +1,30 @@
|
||||
// Copyright 2008 Google Inc.
|
||||
//
|
||||
// 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.reviewdb;
|
||||
|
||||
import com.google.gwtorm.client.Access;
|
||||
import com.google.gwtorm.client.OrmException;
|
||||
import com.google.gwtorm.client.PrimaryKey;
|
||||
import com.google.gwtorm.client.Query;
|
||||
import com.google.gwtorm.client.ResultSet;
|
||||
|
||||
public interface AccountProjectWatchAccess extends
|
||||
Access<AccountProjectWatch, AccountProjectWatch.Key> {
|
||||
@PrimaryKey("key")
|
||||
AccountProjectWatch get(AccountProjectWatch.Key key) throws OrmException;
|
||||
|
||||
@Query("WHERE key.accountId = ?")
|
||||
ResultSet<AccountProjectWatch> byAccount(Account.Id id) throws OrmException;
|
||||
}
|
@@ -30,4 +30,8 @@ public interface ProjectAccess extends Access<Project, Project.NameKey> {
|
||||
|
||||
@Query("ORDER BY name")
|
||||
ResultSet<Project> all() throws OrmException;
|
||||
|
||||
@Query("WHERE name.name >= ? AND name.name <= ? ORDER BY name LIMIT ?")
|
||||
ResultSet<Project> suggestByName(String nameA, String nameB, int limit)
|
||||
throws OrmException;
|
||||
}
|
||||
|
@@ -53,6 +53,9 @@ public interface ReviewDb extends Schema {
|
||||
@Relation
|
||||
StarredChangeAccess starredChanges();
|
||||
|
||||
@Relation
|
||||
AccountProjectWatchAccess accountProjectWatches();
|
||||
|
||||
@Relation
|
||||
ProjectAccess projects();
|
||||
|
||||
|
@@ -0,0 +1,32 @@
|
||||
// Copyright 2008 Google Inc.
|
||||
//
|
||||
// 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.ui;
|
||||
|
||||
import com.google.gwt.user.client.ui.SimplePanel;
|
||||
import com.google.gwt.user.client.ui.Widget;
|
||||
|
||||
/** Panel for use within a TabPanel to create the widget only on selection. */
|
||||
public abstract class LazyTabChild<T extends Widget> extends SimplePanel {
|
||||
/** @return the widget to display in this panel. */
|
||||
protected abstract T create();
|
||||
|
||||
@Override
|
||||
public void setVisible(final boolean visible) {
|
||||
if (visible && getWidget() == null) {
|
||||
setWidget(create());
|
||||
}
|
||||
super.setVisible(visible);
|
||||
}
|
||||
}
|
@@ -0,0 +1,62 @@
|
||||
// Copyright 2008 Google Inc.
|
||||
//
|
||||
// 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.ui;
|
||||
|
||||
import com.google.gerrit.client.RpcStatus;
|
||||
import com.google.gerrit.client.reviewdb.Project;
|
||||
import com.google.gerrit.client.rpc.GerritCallback;
|
||||
import com.google.gwt.user.client.ui.SuggestOracle;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/** Suggestion Oracle for Project.NameKey entities. */
|
||||
public class ProjectNameSuggestOracle extends SuggestOracle {
|
||||
@Override
|
||||
public void requestSuggestions(final Request req, final Callback callback) {
|
||||
RpcStatus.hide(new Runnable() {
|
||||
public void run() {
|
||||
SuggestUtil.SVC.suggestProjectNameKey(req.getQuery(), req.getLimit(),
|
||||
new GerritCallback<List<Project.NameKey>>() {
|
||||
public void onSuccess(final List<Project.NameKey> result) {
|
||||
final ArrayList<ProjectNameSuggestion> r =
|
||||
new ArrayList<ProjectNameSuggestion>(result.size());
|
||||
for (final Project.NameKey p : result) {
|
||||
r.add(new ProjectNameSuggestion(p));
|
||||
}
|
||||
callback.onSuggestionsReady(req, new Response(r));
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static class ProjectNameSuggestion implements
|
||||
SuggestOracle.Suggestion {
|
||||
private final Project.NameKey key;
|
||||
|
||||
ProjectNameSuggestion(final Project.NameKey k) {
|
||||
key = k;
|
||||
}
|
||||
|
||||
public String getDisplayString() {
|
||||
return key.get();
|
||||
}
|
||||
|
||||
public String getReplacementString() {
|
||||
return key.get();
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,28 @@
|
||||
// Copyright 2008 Google Inc.
|
||||
//
|
||||
// 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.ui;
|
||||
|
||||
import com.google.gerrit.client.reviewdb.Project;
|
||||
import com.google.gwt.user.client.rpc.AsyncCallback;
|
||||
import com.google.gwtjsonrpc.client.AllowCrossSiteRequest;
|
||||
import com.google.gwtjsonrpc.client.RemoteJsonService;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface SuggestService extends RemoteJsonService {
|
||||
@AllowCrossSiteRequest
|
||||
void suggestProjectNameKey(String query, int limit,
|
||||
AsyncCallback<List<Project.NameKey>> callback);
|
||||
}
|
@@ -0,0 +1,50 @@
|
||||
// Copyright 2008 Google Inc.
|
||||
//
|
||||
// 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.ui;
|
||||
|
||||
import com.google.gerrit.client.reviewdb.Project;
|
||||
import com.google.gerrit.client.reviewdb.ReviewDb;
|
||||
import com.google.gerrit.client.rpc.BaseServiceImplementation;
|
||||
import com.google.gwt.user.client.rpc.AsyncCallback;
|
||||
import com.google.gwtorm.client.OrmException;
|
||||
import com.google.gwtorm.client.SchemaFactory;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class SuggestServiceImpl extends BaseServiceImplementation implements
|
||||
SuggestService {
|
||||
public SuggestServiceImpl(final SchemaFactory<ReviewDb> rdf) {
|
||||
super(rdf);
|
||||
}
|
||||
|
||||
public void suggestProjectNameKey(final String query, final int limit,
|
||||
final AsyncCallback<List<Project.NameKey>> callback) {
|
||||
run(callback, new Action<List<Project.NameKey>>() {
|
||||
public List<Project.NameKey> run(final ReviewDb db) throws OrmException {
|
||||
final String a = query;
|
||||
final String b = a + "\uffff";
|
||||
final int max = 10;
|
||||
final int n = limit <= 0 ? max : Math.min(limit, max);
|
||||
|
||||
final List<Project.NameKey> r = new ArrayList<Project.NameKey>();
|
||||
for (final Project p : db.projects().suggestByName(a, b, n)) {
|
||||
r.add(p.getNameKey());
|
||||
}
|
||||
return r;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
@@ -0,0 +1,30 @@
|
||||
// Copyright 2008 Google Inc.
|
||||
//
|
||||
// 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.ui;
|
||||
|
||||
import com.google.gwt.core.client.GWT;
|
||||
import com.google.gwtjsonrpc.client.JsonUtil;
|
||||
|
||||
public class SuggestUtil {
|
||||
public static final SuggestService SVC;
|
||||
|
||||
static {
|
||||
SVC = GWT.create(SuggestService.class);
|
||||
JsonUtil.bind(SVC, "rpc/SuggestService");
|
||||
}
|
||||
|
||||
private SuggestUtil() {
|
||||
}
|
||||
}
|
@@ -34,6 +34,14 @@
|
||||
font-size: 8pt;
|
||||
}
|
||||
|
||||
.gerrit-InputFieldTypeHint {
|
||||
color: grey;
|
||||
}
|
||||
|
||||
.gerrit-SmallHeading {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
|
||||
/** Menu **/
|
||||
.gerrit-LinkMenuBar .gwt-MenuItem {
|
||||
@@ -71,6 +79,7 @@
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
float: left;
|
||||
top: 6px;
|
||||
}
|
||||
|
||||
.gerrit-RpcStatus {
|
||||
@@ -496,6 +505,10 @@
|
||||
background-color: #d4e9a9;
|
||||
padding: 5px 5px 5px 5px;
|
||||
}
|
||||
.gerrit-AddSshKeyPanel .gwt-Label {
|
||||
font-weight: bold;
|
||||
|
||||
.gerrit-WatchedProjectPanel {
|
||||
margin-top: 10px;
|
||||
padding: 5px 5px 5px 5px;
|
||||
display: table;
|
||||
border: 1px solid #B0BDCC;
|
||||
}
|
||||
|
@@ -0,0 +1,25 @@
|
||||
// Copyright 2008 Google Inc.
|
||||
//
|
||||
// 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.server;
|
||||
|
||||
import com.google.gerrit.client.ui.SuggestServiceImpl;
|
||||
|
||||
/** Publishes {@link SuggestServiceImpl} over JSON. */
|
||||
public class SuggestServiceSrv extends GerritJsonServlet {
|
||||
@Override
|
||||
protected Object createServiceHandle() throws Exception {
|
||||
return new SuggestServiceImpl(GerritServer.getInstance().getDatabase());
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user