GWT UI: Support moving changes to another branch
Bug: Issue 117 Bug: Issue 6844 Change-Id: I9ad38b5be0a8be4ad31a051ef17a2de46b15b7eb
This commit is contained in:
@@ -43,6 +43,7 @@ class Actions extends Composite {
|
||||
"description",
|
||||
"followup",
|
||||
"hashtags",
|
||||
"move",
|
||||
"publish",
|
||||
"rebase",
|
||||
"restore",
|
||||
@@ -58,6 +59,7 @@ class Actions extends Composite {
|
||||
private static final Binder uiBinder = GWT.create(Binder.class);
|
||||
|
||||
@UiField Button cherrypick;
|
||||
@UiField Button move;
|
||||
@UiField Button rebase;
|
||||
@UiField Button revert;
|
||||
@UiField Button submit;
|
||||
@@ -124,6 +126,7 @@ class Actions extends Composite {
|
||||
if (hasUser) {
|
||||
a2b(actions, "abandon", abandon);
|
||||
a2b(actions, "/", deleteChange);
|
||||
a2b(actions, "move", move);
|
||||
a2b(actions, "restore", restore);
|
||||
a2b(actions, "revert", revert);
|
||||
a2b(actions, "followup", followUp);
|
||||
@@ -236,6 +239,11 @@ class Actions extends Composite {
|
||||
CherryPickAction.call(cherrypick, changeInfo, revision, project, message);
|
||||
}
|
||||
|
||||
@UiHandler("move")
|
||||
void onMove(@SuppressWarnings("unused") ClickEvent e) {
|
||||
MoveAction.call(move, changeInfo, project);
|
||||
}
|
||||
|
||||
@UiHandler("revert")
|
||||
void onRevert(@SuppressWarnings("unused") ClickEvent e) {
|
||||
RevertAction.call(revert, changeId, project, revision, subject);
|
||||
|
||||
@@ -63,6 +63,9 @@ limitations under the License.
|
||||
<g:Button ui:field='cherrypick' styleName='' visible='false'>
|
||||
<div><ui:msg>Cherry Pick</ui:msg></div>
|
||||
</g:Button>
|
||||
<g:Button ui:field='move' styleName='' visible='false'>
|
||||
<div><ui:msg>Move Change</ui:msg></div>
|
||||
</g:Button>
|
||||
<g:Button ui:field='rebase' styleName='' visible='false'>
|
||||
<div><ui:msg>Rebase</ui:msg></div>
|
||||
</g:Button>
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
// Copyright (C) 2017 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.Gerrit;
|
||||
import com.google.gerrit.client.changes.ChangeApi;
|
||||
import com.google.gerrit.client.changes.Util;
|
||||
import com.google.gerrit.client.info.ChangeInfo;
|
||||
import com.google.gerrit.client.rpc.GerritCallback;
|
||||
import com.google.gerrit.client.ui.MoveDialog;
|
||||
import com.google.gerrit.common.PageLinks;
|
||||
import com.google.gerrit.reviewdb.client.Project;
|
||||
import com.google.gwt.event.logical.shared.CloseEvent;
|
||||
import com.google.gwt.user.client.ui.Button;
|
||||
import com.google.gwt.user.client.ui.PopupPanel;
|
||||
|
||||
class MoveAction {
|
||||
static void call(Button b, ChangeInfo info, Project.NameKey project) {
|
||||
b.setEnabled(false);
|
||||
new MoveDialog(project) {
|
||||
{
|
||||
sendButton.setText(Util.C.moveChangeSend());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSend() {
|
||||
ChangeApi.move(
|
||||
info.project(),
|
||||
info.legacyId().get(),
|
||||
getDestinationBranch(),
|
||||
getMessageText(),
|
||||
new GerritCallback<ChangeInfo>() {
|
||||
@Override
|
||||
public void onSuccess(ChangeInfo result) {
|
||||
sent = true;
|
||||
hide();
|
||||
Gerrit.display(PageLinks.toChange(project, result.legacyId()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(Throwable caught) {
|
||||
enableButtons(true);
|
||||
super.onFailure(caught);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClose(CloseEvent<PopupPanel> event) {
|
||||
super.onClose(event);
|
||||
b.setEnabled(true);
|
||||
}
|
||||
}.center();
|
||||
}
|
||||
}
|
||||
@@ -228,6 +228,15 @@ public class ChangeApi {
|
||||
call(project, id, commit, "cherrypick").post(cherryPickInput, cb);
|
||||
}
|
||||
|
||||
/** Move change to another branch. */
|
||||
public static void move(
|
||||
String project, int id, String destination, String message, AsyncCallback<ChangeInfo> cb) {
|
||||
MoveInput moveInput = MoveInput.create();
|
||||
moveInput.setMessage(message);
|
||||
moveInput.setDestinationBranch(destination);
|
||||
change(project, id).view("move").post(moveInput, cb);
|
||||
}
|
||||
|
||||
/** Edit commit message for specific revision of a change. */
|
||||
public static void message(
|
||||
@Nullable String project,
|
||||
@@ -356,6 +365,18 @@ public class ChangeApi {
|
||||
protected CherryPickInput() {}
|
||||
}
|
||||
|
||||
private static class MoveInput extends JavaScriptObject {
|
||||
static MoveInput create() {
|
||||
return (MoveInput) createObject();
|
||||
}
|
||||
|
||||
final native void setDestinationBranch(String d) /*-{ this.destination_branch = d; }-*/;
|
||||
|
||||
final native void setMessage(String m) /*-{ this.message = m; }-*/;
|
||||
|
||||
protected MoveInput() {}
|
||||
}
|
||||
|
||||
private static class PrivateInput extends JavaScriptObject {
|
||||
static PrivateInput create() {
|
||||
return (PrivateInput) createObject();
|
||||
|
||||
@@ -145,6 +145,14 @@ public interface ChangeConstants extends Constants {
|
||||
|
||||
String cherryPickTitle();
|
||||
|
||||
String moveChangeSend();
|
||||
|
||||
String headingMoveBranch();
|
||||
|
||||
String moveChangeMessage();
|
||||
|
||||
String moveTitle();
|
||||
|
||||
String buttonRebaseChangeSend();
|
||||
|
||||
String rebaseConfirmMessage();
|
||||
|
||||
@@ -78,6 +78,11 @@ headingCherryPickBranch = Cherry Pick to Branch:
|
||||
cherryPickCommitMessage = Cherry Pick Commit Message:
|
||||
cherryPickTitle = Code Review - Cherry Pick Change to Another Branch
|
||||
|
||||
headingMoveBranch = Move Change to Branch:
|
||||
moveChangeSend = Move Change
|
||||
moveChangeMessage = Move Change Message:
|
||||
moveTitle = Code Review - Move Change to Another Branch
|
||||
|
||||
buttonRebaseChangeSend = Rebase
|
||||
rebaseConfirmMessage = Change parent revision
|
||||
rebaseNotPossibleMessage = Change is already up to date
|
||||
|
||||
@@ -0,0 +1,107 @@
|
||||
// Copyright (C) 2017 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.ui;
|
||||
|
||||
import com.google.gerrit.client.Gerrit;
|
||||
import com.google.gerrit.client.changes.Util;
|
||||
import com.google.gerrit.client.projects.BranchInfo;
|
||||
import com.google.gerrit.client.projects.ProjectApi;
|
||||
import com.google.gerrit.client.rpc.GerritCallback;
|
||||
import com.google.gerrit.client.rpc.Natives;
|
||||
import com.google.gerrit.reviewdb.client.Project;
|
||||
import com.google.gwt.core.client.JsArray;
|
||||
import com.google.gwt.user.client.ui.FlowPanel;
|
||||
import com.google.gwt.user.client.ui.SuggestBox;
|
||||
import com.google.gwt.user.client.ui.SuggestOracle.Suggestion;
|
||||
import com.google.gwtexpui.globalkey.client.GlobalKey;
|
||||
import com.google.gwtexpui.safehtml.client.HighlightSuggestOracle;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public abstract class MoveDialog extends TextAreaActionDialog {
|
||||
private SuggestBox newBranch;
|
||||
private List<BranchInfo> branches;
|
||||
|
||||
public MoveDialog(Project.NameKey project) {
|
||||
super(Util.C.moveTitle(), Util.C.moveChangeMessage());
|
||||
ProjectApi.getBranches(
|
||||
project,
|
||||
new GerritCallback<JsArray<BranchInfo>>() {
|
||||
@Override
|
||||
public void onSuccess(JsArray<BranchInfo> result) {
|
||||
branches = Natives.asList(result);
|
||||
}
|
||||
});
|
||||
|
||||
newBranch =
|
||||
new SuggestBox(
|
||||
new HighlightSuggestOracle() {
|
||||
@Override
|
||||
protected void onRequestSuggestions(Request request, Callback done) {
|
||||
List<BranchSuggestion> suggestions = new ArrayList<>();
|
||||
for (BranchInfo b : branches) {
|
||||
if (b.ref().contains(request.getQuery())) {
|
||||
suggestions.add(new BranchSuggestion(b));
|
||||
}
|
||||
}
|
||||
done.onSuggestionsReady(request, new Response(suggestions));
|
||||
}
|
||||
});
|
||||
|
||||
newBranch.setWidth("100%");
|
||||
newBranch.getElement().getStyle().setProperty("boxSizing", "border-box");
|
||||
message.setCharacterWidth(70);
|
||||
|
||||
FlowPanel mwrap = new FlowPanel();
|
||||
mwrap.setStyleName(Gerrit.RESOURCES.css().commentedActionMessage());
|
||||
mwrap.add(newBranch);
|
||||
|
||||
panel.insert(mwrap, 0);
|
||||
panel.insert(new SmallHeading(Util.C.headingMoveBranch()), 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void center() {
|
||||
super.center();
|
||||
GlobalKey.dialog(this);
|
||||
newBranch.setFocus(true);
|
||||
}
|
||||
|
||||
public String getDestinationBranch() {
|
||||
return newBranch.getText();
|
||||
}
|
||||
|
||||
static class BranchSuggestion implements Suggestion {
|
||||
private BranchInfo branch;
|
||||
|
||||
BranchSuggestion(BranchInfo branch) {
|
||||
this.branch = branch;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDisplayString() {
|
||||
String refsHeads = "refs/heads/";
|
||||
if (branch.ref().startsWith(refsHeads)) {
|
||||
return branch.ref().substring(refsHeads.length());
|
||||
}
|
||||
return branch.ref();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getReplacementString() {
|
||||
return branch.getShortName();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -23,6 +23,7 @@ import com.google.gerrit.extensions.common.ChangeInfo;
|
||||
import com.google.gerrit.extensions.restapi.AuthException;
|
||||
import com.google.gerrit.extensions.restapi.ResourceConflictException;
|
||||
import com.google.gerrit.extensions.restapi.RestApiException;
|
||||
import com.google.gerrit.extensions.webui.UiAction;
|
||||
import com.google.gerrit.reviewdb.client.Branch;
|
||||
import com.google.gerrit.reviewdb.client.Change;
|
||||
import com.google.gerrit.reviewdb.client.Change.Status;
|
||||
@@ -40,6 +41,7 @@ import com.google.gerrit.server.notedb.ChangeUpdate;
|
||||
import com.google.gerrit.server.permissions.ChangePermission;
|
||||
import com.google.gerrit.server.permissions.PermissionBackend;
|
||||
import com.google.gerrit.server.permissions.PermissionBackendException;
|
||||
import com.google.gerrit.server.permissions.ProjectPermission;
|
||||
import com.google.gerrit.server.permissions.RefPermission;
|
||||
import com.google.gerrit.server.query.change.InternalChangeQuery;
|
||||
import com.google.gerrit.server.update.BatchUpdate;
|
||||
@@ -60,7 +62,8 @@ import org.eclipse.jgit.revwalk.RevCommit;
|
||||
import org.eclipse.jgit.revwalk.RevWalk;
|
||||
|
||||
@Singleton
|
||||
public class Move extends RetryingRestModifyView<ChangeResource, MoveInput, ChangeInfo> {
|
||||
public class Move extends RetryingRestModifyView<ChangeResource, MoveInput, ChangeInfo>
|
||||
implements UiAction<ChangeResource> {
|
||||
private final PermissionBackend permissionBackend;
|
||||
private final Provider<ReviewDb> dbProvider;
|
||||
private final ChangeJson.Factory json;
|
||||
@@ -209,4 +212,16 @@ public class Move extends RetryingRestModifyView<ChangeResource, MoveInput, Chan
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public UiAction.Description getDescription(ChangeResource rsrc) {
|
||||
return new UiAction.Description()
|
||||
.setLabel("Move Change")
|
||||
.setTitle("Move change to a different branch")
|
||||
.setVisible(
|
||||
permissionBackend
|
||||
.user(rsrc.getUser())
|
||||
.project(rsrc.getProject())
|
||||
.testOrFalse(ProjectPermission.CREATE_CHANGE));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user