Add branch actions to Projects > Branches view
Enumerate any RestViews which implement UiAction for BranchResource and generate buttons for these in the web UI. This allows the Codenvy plugin to contribute an Edit button next to each branch. Change-Id: Iaa95ccf560036b928066684a4ca33b6b27b08ab6
This commit is contained in:
@@ -168,8 +168,9 @@ on a button associated with a server side `UiAction`.
|
||||
self.onAction(type, view_name, callback);
|
||||
----
|
||||
|
||||
* type: `'change'`, `'revision'` or `'project'`, indicating which type
|
||||
of resource the `UiAction` was bound to in the server.
|
||||
* type: `'change'`, `'revision'`, `'project'`, or `'branch'`
|
||||
indicating which type of resource the `UiAction` was bound to
|
||||
in the server.
|
||||
|
||||
* view_name: string appearing in URLs to name the view. This is the
|
||||
second argument of the `get()`, `post()`, `put()`, and `delete()`
|
||||
@@ -837,8 +838,8 @@ on a button associated with a server side `UiAction`.
|
||||
Gerrit.onAction(type, view_name, callback);
|
||||
----
|
||||
|
||||
* type: `'change'` or `'revision'`, indicating what sort of resource
|
||||
the `UiAction` was bound to in the server.
|
||||
* type: `'change'`, `'revision'`, `'project'` or `'branch'` indicating
|
||||
what sort of resource the `UiAction` was bound to in the server.
|
||||
|
||||
* view_name: string appearing in URLs to name the view. This is the
|
||||
second argument of the `get()`, `post()`, `put()`, and `delete()`
|
||||
|
@@ -20,6 +20,7 @@ import com.google.gerrit.client.api.ProjectGlue;
|
||||
import com.google.gerrit.client.api.RevisionGlue;
|
||||
import com.google.gerrit.client.changes.ChangeInfo;
|
||||
import com.google.gerrit.client.changes.ChangeInfo.RevisionInfo;
|
||||
import com.google.gerrit.client.projects.BranchInfo;
|
||||
import com.google.gerrit.reviewdb.client.Project;
|
||||
import com.google.gwt.event.dom.client.ClickEvent;
|
||||
import com.google.gwt.event.dom.client.ClickHandler;
|
||||
@@ -28,13 +29,19 @@ import com.google.gwtexpui.safehtml.client.SafeHtmlBuilder;
|
||||
|
||||
public class ActionButton extends Button implements ClickHandler {
|
||||
private final Project.NameKey project;
|
||||
private final BranchInfo branch;
|
||||
private final ChangeInfo change;
|
||||
private final RevisionInfo revision;
|
||||
private final ActionInfo action;
|
||||
private ActionContext ctx;
|
||||
|
||||
public ActionButton(Project.NameKey project, ActionInfo action) {
|
||||
this(project, null, null, action);
|
||||
this(project, null, null, null, action);
|
||||
}
|
||||
|
||||
public ActionButton(Project.NameKey project, BranchInfo branch,
|
||||
ActionInfo action) {
|
||||
this(project, branch, null, null, action);
|
||||
}
|
||||
|
||||
public ActionButton(ChangeInfo change, ActionInfo action) {
|
||||
@@ -43,11 +50,11 @@ public class ActionButton extends Button implements ClickHandler {
|
||||
|
||||
public ActionButton(ChangeInfo change, RevisionInfo revision,
|
||||
ActionInfo action) {
|
||||
this(null, change, revision, action);
|
||||
this(null, null, change, revision, action);
|
||||
}
|
||||
|
||||
private ActionButton(Project.NameKey project, ChangeInfo change,
|
||||
RevisionInfo revision, ActionInfo action) {
|
||||
private ActionButton(Project.NameKey project, BranchInfo branch,
|
||||
ChangeInfo change, RevisionInfo revision, ActionInfo action) {
|
||||
super(new SafeHtmlBuilder()
|
||||
.openDiv()
|
||||
.append(action.label())
|
||||
@@ -58,6 +65,7 @@ public class ActionButton extends Button implements ClickHandler {
|
||||
addClickHandler(this);
|
||||
|
||||
this.project = project;
|
||||
this.branch = branch;
|
||||
this.change = change;
|
||||
this.revision = revision;
|
||||
this.action = action;
|
||||
@@ -75,6 +83,8 @@ public class ActionButton extends Button implements ClickHandler {
|
||||
RevisionGlue.onAction(change, revision, action, this);
|
||||
} else if (change != null) {
|
||||
ChangeGlue.onAction(change, action, this);
|
||||
} else if (branch != null) {
|
||||
ProjectGlue.onAction(project, branch, action, this);
|
||||
} else if (project != null) {
|
||||
ProjectGlue.onAction(project, action, this);
|
||||
}
|
||||
|
@@ -22,6 +22,8 @@ import com.google.gerrit.client.GitwebLink;
|
||||
import com.google.gerrit.client.VoidResult;
|
||||
import com.google.gerrit.client.access.AccessMap;
|
||||
import com.google.gerrit.client.access.ProjectAccessInfo;
|
||||
import com.google.gerrit.client.actions.ActionButton;
|
||||
import com.google.gerrit.client.actions.ActionInfo;
|
||||
import com.google.gerrit.client.projects.BranchInfo;
|
||||
import com.google.gerrit.client.projects.ProjectApi;
|
||||
import com.google.gerrit.client.rpc.GerritCallback;
|
||||
@@ -387,10 +389,18 @@ public class ProjectBranchesScreen extends ProjectScreen {
|
||||
table.setText(row, 3, "");
|
||||
}
|
||||
|
||||
FlowPanel actionsPanel = new FlowPanel();
|
||||
if (c != null) {
|
||||
table.setWidget(row, 4, new Anchor(c.getLinkName(), false,
|
||||
actionsPanel.add(new Anchor(c.getLinkName(), false,
|
||||
c.toBranch(new Branch.NameKey(getProjectKey(), k.ref()))));
|
||||
}
|
||||
if (k.actions() != null) {
|
||||
k.actions().copyKeysIntoChildren("id");
|
||||
for (ActionInfo a : Natives.asList(k.actions().values())) {
|
||||
actionsPanel.add(new ActionButton(getProjectKey(), k, a));
|
||||
}
|
||||
}
|
||||
table.setWidget(row, 4, actionsPanel);
|
||||
|
||||
final FlexCellFormatter fmt = table.getFlexCellFormatter();
|
||||
String iconCellStyle = Gerrit.RESOURCES.css().iconCell();
|
||||
|
@@ -18,6 +18,7 @@ import com.google.gerrit.client.actions.ActionButton;
|
||||
import com.google.gerrit.client.actions.ActionInfo;
|
||||
import com.google.gerrit.client.changes.ChangeInfo;
|
||||
import com.google.gerrit.client.changes.ChangeInfo.RevisionInfo;
|
||||
import com.google.gerrit.client.projects.BranchInfo;
|
||||
import com.google.gerrit.client.rpc.GerritCallback;
|
||||
import com.google.gerrit.client.rpc.NativeString;
|
||||
import com.google.gerrit.client.rpc.RestApi;
|
||||
@@ -136,6 +137,7 @@ public class ActionContext extends JavaScriptObject {
|
||||
final native void set(ActionInfo a) /*-{ this.action=a; }-*/;
|
||||
final native void set(ChangeInfo c) /*-{ this.change=c; }-*/;
|
||||
final native void set(Project.NameKey p) /*-{ this.project=p; }-*/;
|
||||
final native void set(BranchInfo b) /*-{ this.branch=b }-*/;
|
||||
final native void set(RevisionInfo r) /*-{ this.revision=r; }-*/;
|
||||
|
||||
final native void button(ActionButton b) /*-{ this._b=b; }-*/;
|
||||
|
@@ -43,6 +43,7 @@ public class ApiGlue {
|
||||
change_actions: {},
|
||||
revision_actions: {},
|
||||
project_actions: {},
|
||||
branch_actions: {},
|
||||
|
||||
getPluginName: @com.google.gerrit.client.api.ApiGlue::getPluginName(),
|
||||
injectCss: @com.google.gwt.dom.client.StyleInjector::inject(Ljava/lang/String;),
|
||||
@@ -71,6 +72,7 @@ public class ApiGlue {
|
||||
if ('change' == t) this.change_actions[i]=c;
|
||||
else if ('revision' == t) this.revision_actions[i]=c;
|
||||
else if ('project' == t) this.project_actions[i]=c;
|
||||
else if ('branch' == t) this.branch_actions[i]=c;
|
||||
else if ('screen' == t) _screen(p,t,c);
|
||||
},
|
||||
screen: function(r,c){this._screen(this.getPluginName(),r,c)},
|
||||
|
@@ -16,18 +16,40 @@ package com.google.gerrit.client.api;
|
||||
|
||||
import com.google.gerrit.client.actions.ActionButton;
|
||||
import com.google.gerrit.client.actions.ActionInfo;
|
||||
import com.google.gerrit.client.projects.BranchInfo;
|
||||
import com.google.gerrit.client.projects.ProjectApi;
|
||||
import com.google.gerrit.client.rpc.RestApi;
|
||||
import com.google.gerrit.reviewdb.client.Project;
|
||||
import com.google.gwt.core.client.JavaScriptObject;
|
||||
|
||||
public class ProjectGlue {
|
||||
public static void onAction(
|
||||
Project.NameKey project,
|
||||
BranchInfo branch,
|
||||
ActionInfo action,
|
||||
ActionButton button) {
|
||||
RestApi api = ProjectApi.project(project)
|
||||
.view("branches").id(branch.ref())
|
||||
.view(action.id());
|
||||
JavaScriptObject f = branchAction(action.id());
|
||||
if (f != null) {
|
||||
ActionContext c = ActionContext.create(api);
|
||||
c.set(action);
|
||||
c.set(project);
|
||||
c.set(branch);
|
||||
c.button(button);
|
||||
ApiGlue.invoke(f, c);
|
||||
} else {
|
||||
DefaultActions.invoke(project, action, api);
|
||||
}
|
||||
}
|
||||
|
||||
public static void onAction(
|
||||
Project.NameKey project,
|
||||
ActionInfo action,
|
||||
ActionButton button) {
|
||||
RestApi api = ProjectApi.project(project).view(action.id());
|
||||
JavaScriptObject f = get(action.id());
|
||||
JavaScriptObject f = projectAction(action.id());
|
||||
if (f != null) {
|
||||
ActionContext c = ActionContext.create(api);
|
||||
c.set(action);
|
||||
@@ -39,10 +61,14 @@ public class ProjectGlue {
|
||||
}
|
||||
}
|
||||
|
||||
private static final native JavaScriptObject get(String id) /*-{
|
||||
private static final native JavaScriptObject projectAction(String id) /*-{
|
||||
return $wnd.Gerrit.project_actions[id];
|
||||
}-*/;
|
||||
|
||||
private static final native JavaScriptObject branchAction(String id) /*-{
|
||||
return $wnd.Gerrit.branch_actions[id];
|
||||
}-*/;
|
||||
|
||||
private ProjectGlue() {
|
||||
}
|
||||
}
|
||||
|
@@ -14,6 +14,8 @@
|
||||
|
||||
package com.google.gerrit.client.projects;
|
||||
|
||||
import com.google.gerrit.client.actions.ActionInfo;
|
||||
import com.google.gerrit.client.rpc.NativeMap;
|
||||
import com.google.gerrit.reviewdb.client.Branch;
|
||||
import com.google.gwt.core.client.JavaScriptObject;
|
||||
|
||||
@@ -27,6 +29,7 @@ public class BranchInfo extends JavaScriptObject {
|
||||
public final native String ref() /*-{ return this.ref; }-*/;
|
||||
public final native String revision() /*-{ return this.revision; }-*/;
|
||||
public final native boolean canDelete() /*-{ return this['can_delete'] ? true : false; }-*/;
|
||||
public final native NativeMap<ActionInfo> actions() /*-{ return this.actions }-*/;
|
||||
|
||||
protected BranchInfo() {
|
||||
}
|
||||
|
@@ -16,11 +16,17 @@ package com.google.gerrit.server.project;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.google.gerrit.extensions.common.ActionInfo;
|
||||
import com.google.gerrit.extensions.registration.DynamicMap;
|
||||
import com.google.gerrit.extensions.restapi.ResourceNotFoundException;
|
||||
import com.google.gerrit.extensions.restapi.RestReadView;
|
||||
import com.google.gerrit.extensions.restapi.RestView;
|
||||
import com.google.gerrit.extensions.webui.UiAction;
|
||||
import com.google.gerrit.reviewdb.client.RefNames;
|
||||
import com.google.gerrit.server.extensions.webui.UiActions;
|
||||
import com.google.gerrit.server.git.GitRepositoryManager;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.util.Providers;
|
||||
|
||||
import org.eclipse.jgit.errors.RepositoryNotFoundException;
|
||||
import org.eclipse.jgit.lib.Constants;
|
||||
@@ -34,14 +40,17 @@ import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.TreeMap;
|
||||
|
||||
public class ListBranches implements RestReadView<ProjectResource> {
|
||||
|
||||
private final GitRepositoryManager repoManager;
|
||||
private final DynamicMap<RestView<BranchResource>> branchViews;
|
||||
|
||||
@Inject
|
||||
public ListBranches(GitRepositoryManager repoManager) {
|
||||
public ListBranches(GitRepositoryManager repoManager,
|
||||
DynamicMap<RestView<BranchResource>> branchViews) {
|
||||
this.repoManager = repoManager;
|
||||
this.branchViews = branchViews;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -136,17 +145,28 @@ public class ListBranches implements RestReadView<ProjectResource> {
|
||||
return branches;
|
||||
}
|
||||
|
||||
private static BranchInfo createBranchInfo(Ref ref, RefControl refControl,
|
||||
private BranchInfo createBranchInfo(Ref ref, RefControl refControl,
|
||||
Set<String> targets) {
|
||||
return new BranchInfo(ref.getName(),
|
||||
BranchInfo info = new BranchInfo(ref.getName(),
|
||||
ref.getObjectId() != null ? ref.getObjectId().name() : null,
|
||||
!targets.contains(ref.getName()) && refControl.canDelete());
|
||||
for (UiAction.Description d : UiActions.from(
|
||||
branchViews,
|
||||
new BranchResource(refControl.getProjectControl(), info),
|
||||
Providers.of(refControl.getCurrentUser()))) {
|
||||
if (info.actions == null) {
|
||||
info.actions = new TreeMap<>();
|
||||
}
|
||||
info.actions.put(d.getId(), new ActionInfo(d));
|
||||
}
|
||||
return info;
|
||||
}
|
||||
|
||||
public static class BranchInfo {
|
||||
public String ref;
|
||||
public String revision;
|
||||
public Boolean canDelete;
|
||||
public Map<String, ActionInfo> actions;
|
||||
|
||||
public BranchInfo(String ref, String revision, boolean canDelete) {
|
||||
this.ref = ref;
|
||||
|
Reference in New Issue
Block a user