Add option to make approved patches be auto-submitted

Add a "Publish & Submit" button to the web review screen.  This
button performs the actions that the "Publish Comments" button
performs while additionally submitting the patch for merging.

Bug: issue 391
Change-Id: If9f3415be1378e9303afe34486dce557a926dc71
This commit is contained in:
Martin Fick
2010-06-10 15:23:26 -06:00
committed by Shawn O. Pearce
parent cc468b1cf7
commit 6858e2d84f
6 changed files with 60 additions and 10 deletions

View File

@@ -32,6 +32,7 @@ public class PatchSetPublishDetail {
protected List<PatchLineComment> drafts; protected List<PatchLineComment> drafts;
protected Map<ApprovalCategory.Id, Set<ApprovalCategoryValue.Id>> allowed; protected Map<ApprovalCategory.Id, Set<ApprovalCategoryValue.Id>> allowed;
protected Map<ApprovalCategory.Id, PatchSetApproval> given; protected Map<ApprovalCategory.Id, PatchSetApproval> given;
protected boolean isSubmitAllowed;
public Map<ApprovalCategory.Id, Set<ApprovalCategoryValue.Id>> getAllowed() { public Map<ApprovalCategory.Id, Set<ApprovalCategoryValue.Id>> getAllowed() {
return allowed; return allowed;
@@ -66,6 +67,10 @@ public class PatchSetPublishDetail {
this.drafts = drafts; this.drafts = drafts;
} }
public void setSubmitAllowed(boolean allowed) {
isSubmitAllowed = allowed;
}
public AccountInfoCache getAccounts() { public AccountInfoCache getAccounts() {
return accounts; return accounts;
} }
@@ -94,4 +99,8 @@ public class PatchSetPublishDetail {
public PatchSetApproval getChangeApproval(final ApprovalCategory.Id id) { public PatchSetApproval getChangeApproval(final ApprovalCategory.Id id) {
return given.get(id); return given.get(id);
} }
public boolean isSubmitAllowed() {
return isSubmitAllowed;
}
} }

View File

@@ -96,6 +96,7 @@ public interface ChangeConstants extends Constants {
String buttonReview(); String buttonReview();
String buttonPublishCommentsSend(); String buttonPublishCommentsSend();
String buttonPublishSubmitSend();
String buttonPublishCommentsCancel(); String buttonPublishCommentsCancel();
String headingCoverMessage(); String headingCoverMessage();
String headingPatchComments(); String headingPatchComments();

View File

@@ -73,6 +73,7 @@ abandonChangeTitle = Code Review - Abandon Change
buttonReview = Review buttonReview = Review
buttonPublishCommentsSend = Publish Comments buttonPublishCommentsSend = Publish Comments
buttonPublishSubmitSend = Publish and Submit
buttonPublishCommentsCancel = Cancel buttonPublishCommentsCancel = Cancel
headingCoverMessage = Cover Message: headingCoverMessage = Cover Message:
headingPatchComments = Patch Comments: headingPatchComments = Patch Comments:

View File

@@ -25,6 +25,7 @@ import com.google.gerrit.client.ui.PatchLink;
import com.google.gerrit.client.ui.SmallHeading; import com.google.gerrit.client.ui.SmallHeading;
import com.google.gerrit.common.PageLinks; import com.google.gerrit.common.PageLinks;
import com.google.gerrit.common.data.ApprovalType; import com.google.gerrit.common.data.ApprovalType;
import com.google.gerrit.common.data.ChangeDetail;
import com.google.gerrit.common.data.PatchSetPublishDetail; import com.google.gerrit.common.data.PatchSetPublishDetail;
import com.google.gerrit.reviewdb.ApprovalCategory; import com.google.gerrit.reviewdb.ApprovalCategory;
import com.google.gerrit.reviewdb.ApprovalCategoryValue; import com.google.gerrit.reviewdb.ApprovalCategoryValue;
@@ -67,6 +68,7 @@ public class PublishCommentScreen extends AccountScreen implements
private NpTextArea message; private NpTextArea message;
private FlowPanel draftsPanel; private FlowPanel draftsPanel;
private Button send; private Button send;
private Button submit;
private Button cancel; private Button cancel;
private boolean saveStateOnUnload = true; private boolean saveStateOnUnload = true;
private List<CommentEditorPanel> commentEditors; private List<CommentEditorPanel> commentEditors;
@@ -103,12 +105,17 @@ public class PublishCommentScreen extends AccountScreen implements
body.add(draftsPanel); body.add(draftsPanel);
final FlowPanel buttonRow = new FlowPanel(); final FlowPanel buttonRow = new FlowPanel();
buttonRow.setStyleName(Gerrit.RESOURCES.css().patchSetActions());
body.add(buttonRow); body.add(buttonRow);
send = new Button(Util.C.buttonPublishCommentsSend()); send = new Button(Util.C.buttonPublishCommentsSend());
send.addClickHandler(this); send.addClickHandler(this);
buttonRow.add(send); buttonRow.add(send);
submit = new Button(Util.C.buttonPublishSubmitSend());
submit.addClickHandler(this);
buttonRow.add(submit);
cancel = new Button(Util.C.buttonPublishCommentsCancel()); cancel = new Button(Util.C.buttonPublishCommentsCancel());
cancel.addClickHandler(this); cancel.addClickHandler(this);
buttonRow.add(cancel); buttonRow.add(cancel);
@@ -142,7 +149,9 @@ public class PublishCommentScreen extends AccountScreen implements
public void onClick(final ClickEvent event) { public void onClick(final ClickEvent event) {
final Widget sender = (Widget) event.getSource(); final Widget sender = (Widget) event.getSource();
if (send == sender) { if (send == sender) {
onSend(); onSend(false);
} else if (submit == sender) {
onSend(true);
} else if (cancel == sender) { } else if (cancel == sender) {
saveStateOnUnload = false; saveStateOnUnload = false;
goChange(); goChange();
@@ -250,6 +259,7 @@ public class PublishCommentScreen extends AccountScreen implements
if (r.getChange().getStatus().isOpen()) { if (r.getChange().getStatus().isOpen()) {
initApprovals(r, approvalPanel); initApprovals(r, approvalPanel);
} }
if (lastState != null && patchSetId.equals(lastState.patchSetId)) { if (lastState != null && patchSetId.equals(lastState.patchSetId)) {
message.setText(lastState.message); message.setText(lastState.message);
} }
@@ -285,11 +295,13 @@ public class PublishCommentScreen extends AccountScreen implements
panel.add(editor); panel.add(editor);
} }
} }
submit.setVisible(r.isSubmitAllowed());
} }
private void onSend() { private void onSend(final boolean submit) {
if (commentEditors.isEmpty()) { if (commentEditors.isEmpty()) {
onSend2(); onSend2(submit);
} else { } else {
final GerritCallback<VoidResult> afterSaveDraft = final GerritCallback<VoidResult> afterSaveDraft =
new GerritCallback<VoidResult>() { new GerritCallback<VoidResult>() {
@@ -298,7 +310,7 @@ public class PublishCommentScreen extends AccountScreen implements
@Override @Override
public void onSuccess(final VoidResult result) { public void onSuccess(final VoidResult result) {
if (++done == commentEditors.size()) { if (++done == commentEditors.size()) {
onSend2(); onSend2(submit);
} }
} }
}; };
@@ -308,7 +320,7 @@ public class PublishCommentScreen extends AccountScreen implements
} }
} }
private void onSend2() { private void onSend2(final boolean submit) {
final Map<ApprovalCategory.Id, ApprovalCategoryValue.Id> values = final Map<ApprovalCategory.Id, ApprovalCategoryValue.Id> values =
new HashMap<ApprovalCategory.Id, ApprovalCategoryValue.Id>(); new HashMap<ApprovalCategory.Id, ApprovalCategoryValue.Id>();
for (final ValueRadioButton b : approvalButtons) { for (final ValueRadioButton b : approvalButtons) {
@@ -321,6 +333,20 @@ public class PublishCommentScreen extends AccountScreen implements
new HashSet<ApprovalCategoryValue.Id>(values.values()), new HashSet<ApprovalCategoryValue.Id>(values.values()),
new GerritCallback<VoidResult>() { new GerritCallback<VoidResult>() {
public void onSuccess(final VoidResult result) { public void onSuccess(final VoidResult result) {
if(submit) {
submit();
} else {
saveStateOnUnload = false;
goChange();
}
}
});
}
private void submit() {
Util.MANAGE_SVC.submit(patchSetId,
new GerritCallback<ChangeDetail>() {
public void onSuccess(ChangeDetail result) {
saveStateOnUnload = false; saveStateOnUnload = false;
goChange(); goChange();
} }

View File

@@ -33,6 +33,7 @@ import com.google.gerrit.server.IdentifiedUser;
import com.google.gerrit.server.account.AccountInfoCacheFactory; import com.google.gerrit.server.account.AccountInfoCacheFactory;
import com.google.gerrit.server.patch.PatchSetInfoFactory; import com.google.gerrit.server.patch.PatchSetInfoFactory;
import com.google.gerrit.server.patch.PatchSetInfoNotAvailableException; import com.google.gerrit.server.patch.PatchSetInfoNotAvailableException;
import com.google.gerrit.server.project.CanSubmitResult;
import com.google.gerrit.server.project.ChangeControl; import com.google.gerrit.server.project.ChangeControl;
import com.google.gerrit.server.project.NoSuchChangeException; import com.google.gerrit.server.project.NoSuchChangeException;
import com.google.gerrit.server.project.ProjectCache; import com.google.gerrit.server.project.ProjectCache;
@@ -122,6 +123,9 @@ final class PatchSetPublishDetailFactory extends Handler<PatchSetPublishDetail>
detail.setAllowed(allowed); detail.setAllowed(allowed);
detail.setGiven(given); detail.setGiven(given);
final CanSubmitResult canSubmitResult = control.canSubmit(patchSetId);
detail.setSubmitAllowed(canSubmitResult == CanSubmitResult.OK);
return detail; return detail;
} }

View File

@@ -185,11 +185,7 @@ public class ChangeControl {
} }
/** @return {@link CanSubmitResult#OK}, or a result with an error message. */ /** @return {@link CanSubmitResult#OK}, or a result with an error message. */
public CanSubmitResult canSubmit(final PatchSet.Id patchSetId, final ReviewDb db, public CanSubmitResult canSubmit(final PatchSet.Id patchSetId) {
final ApprovalTypes approvalTypes,
FunctionState.Factory functionStateFactory)
throws OrmException {
if (change.getStatus().isClosed()) { if (change.getStatus().isClosed()) {
return new CanSubmitResult("Change " + change.getId() + " is closed"); return new CanSubmitResult("Change " + change.getId() + " is closed");
} }
@@ -202,6 +198,19 @@ public class ChangeControl {
if (!(getCurrentUser() instanceof IdentifiedUser)) { if (!(getCurrentUser() instanceof IdentifiedUser)) {
return new CanSubmitResult("User is not signed-in"); return new CanSubmitResult("User is not signed-in");
} }
return CanSubmitResult.OK;
}
/** @return {@link CanSubmitResult#OK}, or a result with an error message. */
public CanSubmitResult canSubmit(final PatchSet.Id patchSetId, final ReviewDb db,
final ApprovalTypes approvalTypes,
FunctionState.Factory functionStateFactory)
throws OrmException {
CanSubmitResult result = canSubmit(patchSetId);
if (result != CanSubmitResult.OK) {
return result;
}
final List<PatchSetApproval> allApprovals = final List<PatchSetApproval> allApprovals =
new ArrayList<PatchSetApproval>(db.patchSetApprovals().byPatchSet( new ArrayList<PatchSetApproval>(db.patchSetApprovals().byPatchSet(