blob: 1902d976bf2f5d175b29ae59767b2443318c36a3 [file] [log] [blame]
// Copyright (C) 2013 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.change;
import com.google.gerrit.client.ConfirmationCallback;
import com.google.gerrit.client.ConfirmationDialog;
import com.google.gerrit.client.Gerrit;
import com.google.gerrit.client.account.AccountInfo;
import com.google.gerrit.client.changes.ApprovalTable.PostInput;
import com.google.gerrit.client.changes.ApprovalTable.PostResult;
import com.google.gerrit.client.changes.ChangeApi;
import com.google.gerrit.client.changes.ChangeInfo;
import com.google.gerrit.client.changes.ChangeInfo.ApprovalInfo;
import com.google.gerrit.client.changes.ChangeInfo.LabelInfo;
import com.google.gerrit.client.changes.Util;
import com.google.gerrit.client.rpc.GerritCallback;
import com.google.gerrit.client.rpc.Natives;
import com.google.gerrit.client.ui.HintTextBox;
import com.google.gerrit.reviewdb.client.Change;
import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.Element;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.KeyCodes;
import com.google.gwt.event.dom.client.KeyDownEvent;
import com.google.gwt.event.dom.client.KeyDownHandler;
import com.google.gwt.event.logical.shared.SelectionEvent;
import com.google.gwt.event.logical.shared.SelectionHandler;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.uibinder.client.UiHandler;
import com.google.gwt.user.client.rpc.StatusCodeException;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.HTMLPanel;
import com.google.gwt.user.client.ui.SuggestBox;
import com.google.gwt.user.client.ui.SuggestBox.DefaultSuggestionDisplay;
import com.google.gwt.user.client.ui.SuggestOracle.Suggestion;
import com.google.gwt.user.client.ui.UIObject;
import com.google.gwtexpui.safehtml.client.SafeHtml;
import com.google.gwtexpui.safehtml.client.SafeHtmlBuilder;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
/** Add reviewers. */
class Reviewers extends Composite {
interface Binder extends UiBinder<HTMLPanel, Reviewers> {}
private static final Binder uiBinder = GWT.create(Binder.class);
@UiField Element ccText;
@UiField Button openForm;
@UiField Element form;
@UiField Element error;
@UiField(provided = true)
SuggestBox suggestBox;
private ChangeScreen2.Style style;
private Element reviewersText;
private RestReviewerSuggestOracle reviewerSuggestOracle;
private HintTextBox nameTxtBox;
private Change.Id changeId;
private boolean submitOnSelection;
Reviewers() {
reviewerSuggestOracle = new RestReviewerSuggestOracle();
nameTxtBox = new HintTextBox();
suggestBox = new SuggestBox(reviewerSuggestOracle, nameTxtBox);
initWidget(uiBinder.createAndBindUi(this));
nameTxtBox.setVisibleLength(55);
nameTxtBox.setHintText(Util.C.approvalTableAddReviewerHint());
nameTxtBox.addKeyDownHandler(new KeyDownHandler() {
@Override
public void onKeyDown(KeyDownEvent e) {
submitOnSelection = false;
if (e.getNativeEvent().getKeyCode() == KeyCodes.KEY_ESCAPE) {
onCancel(null);
} else if (e.getNativeEvent().getKeyCode() == KeyCodes.KEY_ENTER) {
if (((DefaultSuggestionDisplay) suggestBox.getSuggestionDisplay())
.isSuggestionListShowing()) {
submitOnSelection = true;
} else {
onAdd(null);
}
}
}
});
suggestBox.addSelectionHandler(new SelectionHandler<Suggestion>() {
@Override
public void onSelection(SelectionEvent<Suggestion> event) {
nameTxtBox.setFocus(true);
if (submitOnSelection) {
onAdd(null);
}
}
});
}
void init(ChangeScreen2.Style style, Element reviewersText) {
this.style = style;
this.reviewersText = reviewersText;
}
void set(ChangeInfo info) {
this.changeId = info.legacy_id();
display(info);
reviewerSuggestOracle.setChange(changeId);
openForm.setVisible(Gerrit.isSignedIn());
}
@UiHandler("openForm")
void onOpenForm(ClickEvent e) {
onOpenForm();
}
void onOpenForm() {
UIObject.setVisible(form, true);
UIObject.setVisible(error, false);
openForm.setVisible(false);
suggestBox.setFocus(true);
}
@UiHandler("add")
void onAdd(ClickEvent e) {
String reviewer = suggestBox.getText();
if (!reviewer.isEmpty()) {
addReviewer(reviewer, false);
}
}
@UiHandler("cancel")
void onCancel(ClickEvent e) {
openForm.setVisible(true);
UIObject.setVisible(form, false);
suggestBox.setFocus(false);
}
private void addReviewer(final String reviewer, boolean confirmed) {
ChangeApi.reviewers(changeId.get()).post(
PostInput.create(reviewer, confirmed),
new GerritCallback<PostResult>() {
public void onSuccess(PostResult result) {
nameTxtBox.setEnabled(true);
if (result.confirm()) {
askForConfirmation(result.error());
} else if (result.error() != null) {
UIObject.setVisible(error, true);
error.setInnerText(result.error());
} else {
UIObject.setVisible(error, false);
error.setInnerText("");
nameTxtBox.setText("");
if (result.reviewers() != null
&& result.reviewers().length() > 0) {
updateReviewerList();
}
}
}
private void askForConfirmation(String text) {
new ConfirmationDialog(
Util.C.approvalTableAddManyReviewersConfirmationDialogTitle(),
new SafeHtmlBuilder().append(text),
new ConfirmationCallback() {
@Override
public void onOk() {
addReviewer(reviewer, true);
}
}).center();
}
@Override
public void onFailure(Throwable err) {
UIObject.setVisible(error, true);
error.setInnerText(err instanceof StatusCodeException
? ((StatusCodeException) err).getEncodedResponse()
: err.getMessage());
nameTxtBox.setEnabled(true);
}
});
}
private void updateReviewerList() {
ChangeApi.detail(changeId.get(),
new GerritCallback<ChangeInfo>() {
@Override
public void onSuccess(ChangeInfo result) {
display(result);
}
});
}
private void display(ChangeInfo info) {
Map<Integer, AccountInfo> r = new HashMap<Integer, AccountInfo>();
Map<Integer, AccountInfo> cc = new HashMap<Integer, AccountInfo>();
for (LabelInfo label : Natives.asList(info.all_labels().values())) {
if (label.all() != null) {
for (ApprovalInfo ai : Natives.asList(label.all())) {
(ai.value() != 0 ? r : cc).put(ai._account_id(), ai);
}
}
}
for (Integer i : r.keySet()) {
cc.remove(i);
}
r.remove(info.owner()._account_id());
cc.remove(info.owner()._account_id());
Set<Integer> removable = new HashSet<Integer>();
if (info.removable_reviewers() != null) {
for (AccountInfo a : Natives.asList(info.removable_reviewers())) {
removable.add(a._account_id());
}
}
SafeHtml rHtml = Labels.formatUserList(style, r.values(), removable);
SafeHtml ccHtml = Labels.formatUserList(style, cc.values(), removable);
reviewersText.setInnerSafeHtml(rHtml);
ccText.setInnerSafeHtml(ccHtml);
}
}