Add additional information in Groups Table.

Add columns for 'Owners', 'Group Type', 'Email Only Authors' and
'Visible To All' into the groups table used by Admin->Groups Screen
and MyGroups Screen. Adding more info to this table helps the
administrators to view the settings and additional info of a group
faster without clicking on each group. This can work as a dashboard
or report that contains the info for all the groups in one place.
As an example, this allows one to quickly find all the groups which
are having emails squelched.

Change-Id: Ia952e9dcecf415c4fce7001a0d28ad4731ff5b1c
This commit is contained in:
Raviteja Sunkara
2011-06-28 20:25:21 +05:30
parent f8d35d7312
commit fccf928042
9 changed files with 70 additions and 19 deletions

View File

@@ -15,9 +15,9 @@
package com.google.gerrit.common.data;
import com.google.gerrit.common.auth.SignInRequired;
import com.google.gerrit.common.data.GroupDetail;
import com.google.gerrit.reviewdb.Account;
import com.google.gerrit.reviewdb.AccountExternalId;
import com.google.gerrit.reviewdb.AccountGroup;
import com.google.gerrit.reviewdb.AccountSshKey;
import com.google.gerrit.reviewdb.ContactInformation;
import com.google.gerrit.reviewdb.ContributorAgreement;
@@ -57,7 +57,7 @@ public interface AccountSecurity extends RemoteJsonService {
void myExternalIds(AsyncCallback<List<AccountExternalId>> callback);
@SignInRequired
void myGroups(AsyncCallback<List<AccountGroup>> callback);
void myGroups(AsyncCallback<List<GroupDetail>> callback);
@SignInRequired
void deleteExternalIds(Set<AccountExternalId.Key> keys,

View File

@@ -14,19 +14,19 @@
package com.google.gerrit.common.data;
import com.google.gerrit.reviewdb.AccountGroup;
import com.google.gerrit.common.data.GroupDetail;
import java.util.List;
public class GroupList {
protected List<AccountGroup> groups;
protected List<GroupDetail> groups;
protected boolean canCreateGroup;
public List<AccountGroup> getGroups() {
public List<GroupDetail> getGroups() {
return groups;
}
public void setGroups(List<AccountGroup> groups) {
public void setGroups(List<GroupDetail> groups) {
this.groups = groups;
}

View File

@@ -16,7 +16,7 @@ package com.google.gerrit.client.account;
import com.google.gerrit.client.admin.GroupTable;
import com.google.gerrit.client.rpc.ScreenLoadCallback;
import com.google.gerrit.reviewdb.AccountGroup;
import com.google.gerrit.common.data.GroupDetail;
import java.util.List;
@@ -33,8 +33,8 @@ public class MyGroupsScreen extends SettingsScreen {
@Override
protected void onLoad() {
super.onLoad();
Util.ACCOUNT_SEC.myGroups(new ScreenLoadCallback<List<AccountGroup>>(this) {
public void preDisplay(final List<AccountGroup> result) {
Util.ACCOUNT_SEC.myGroups(new ScreenLoadCallback<List<GroupDetail>>(this) {
public void preDisplay(final List<GroupDetail> result) {
groups.display(result);
}
});

View File

@@ -71,6 +71,9 @@ public interface AdminConstants extends Constants {
String columnEmailAddress();
String columnGroupName();
String columnGroupDescription();
String columnGroupType();
String columnGroupNotifications();
String columnGroupVisibleToAll();
String columnBranchName();
String columnBranchRevision();

View File

@@ -51,6 +51,9 @@ columnMember = Member
columnEmailAddress = Email Address
columnGroupName = Group Name
columnGroupDescription = Description
columnGroupType = Group Type
columnGroupNotifications = Email Only Authors
columnGroupVisibleToAll = Visible To All
columnBranchName = Branch Name
columnBranchRevision = Revision

View File

@@ -16,8 +16,10 @@ package com.google.gerrit.client.admin;
import com.google.gerrit.client.Dispatcher;
import com.google.gerrit.client.Gerrit;
import com.google.gerrit.client.rpc.GerritCallback;
import com.google.gerrit.client.ui.Hyperlink;
import com.google.gerrit.client.ui.NavigationTable;
import com.google.gerrit.common.data.GroupDetail;
import com.google.gerrit.reviewdb.AccountGroup;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
@@ -25,6 +27,7 @@ import com.google.gwt.event.dom.client.KeyCodes;
import com.google.gwt.user.client.History;
import com.google.gwt.user.client.ui.FlexTable.FlexCellFormatter;
import com.google.gwt.user.client.ui.HTMLTable.Cell;
import com.google.gwt.user.client.ui.Image;
import java.util.List;
@@ -48,6 +51,10 @@ public class GroupTable extends NavigationTable<AccountGroup> {
table.setText(0, 1, Util.C.columnGroupName());
table.setText(0, 2, Util.C.columnGroupDescription());
table.setText(0, 3, Util.C.headingOwner());
table.setText(0, 4, Util.C.columnGroupType());
table.setText(0, 5, Util.C.columnGroupNotifications());
table.setText(0, 6, Util.C.columnGroupVisibleToAll());
table.addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
@@ -62,6 +69,10 @@ public class GroupTable extends NavigationTable<AccountGroup> {
final FlexCellFormatter fmt = table.getFlexCellFormatter();
fmt.addStyleName(0, 1, Gerrit.RESOURCES.css().dataHeader());
fmt.addStyleName(0, 2, Gerrit.RESOURCES.css().dataHeader());
fmt.addStyleName(0, 3, Gerrit.RESOURCES.css().dataHeader());
fmt.addStyleName(0, 4, Gerrit.RESOURCES.css().dataHeader());
fmt.addStyleName(0, 5, Gerrit.RESOURCES.css().dataHeader());
fmt.addStyleName(0, 6, Gerrit.RESOURCES.css().dataHeader());
}
@Override
@@ -74,19 +85,20 @@ public class GroupTable extends NavigationTable<AccountGroup> {
History.newItem(Dispatcher.toGroup(getRowItem(row).getId()));
}
public void display(final List<AccountGroup> result) {
public void display(final List<GroupDetail> result) {
while (1 < table.getRowCount())
table.removeRow(table.getRowCount() - 1);
for (final AccountGroup k : result) {
for(GroupDetail detail : result) {
final int row = table.getRowCount();
table.insertRow(row);
applyDataRowStyle(row);
populate(row, k);
populate(row, detail);
}
}
void populate(final int row, final AccountGroup k) {
void populate(final int row, final GroupDetail detail) {
AccountGroup k = detail.group;
if (enableLink) {
table.setWidget(row, 1, new Hyperlink(k.getName(),
Dispatcher.toGroup(k.getId())));
@@ -94,11 +106,23 @@ public class GroupTable extends NavigationTable<AccountGroup> {
table.setText(row, 1, k.getName());
}
table.setText(row, 2, k.getDescription());
table.setText(row, 3, detail.ownerGroup.getName());
table.setText(row, 4, k.getType().toString());
if (k.isEmailOnlyAuthors()) {
table.setWidget(row, 5, new Image(Gerrit.RESOURCES.greenCheck()));
}
if (k.isVisibleToAll()) {
table.setWidget(row, 6, new Image(Gerrit.RESOURCES.greenCheck()));
}
final FlexCellFormatter fmt = table.getFlexCellFormatter();
fmt.addStyleName(row, 1, Gerrit.RESOURCES.css().dataCell());
fmt.addStyleName(row, 1, Gerrit.RESOURCES.css().groupName());
fmt.addStyleName(row, 2, Gerrit.RESOURCES.css().dataCell());
fmt.addStyleName(row, 3, Gerrit.RESOURCES.css().dataCell());
fmt.addStyleName(row, 4, Gerrit.RESOURCES.css().dataCell());
fmt.addStyleName(row, 5, Gerrit.RESOURCES.css().dataCell());
fmt.addStyleName(row, 6, Gerrit.RESOURCES.css().dataCell());
setRowItem(row, k);
}

View File

@@ -15,10 +15,12 @@
package com.google.gerrit.httpd.rpc.account;
import com.google.gerrit.common.data.AccountSecurity;
import com.google.gerrit.common.data.GroupDetail;
import com.google.gerrit.common.errors.ContactInformationStoreException;
import com.google.gerrit.common.errors.InvalidSshKeyException;
import com.google.gerrit.common.errors.NameAlreadyUsedException;
import com.google.gerrit.common.errors.NoSuchEntityException;
import com.google.gerrit.common.errors.NoSuchGroupException;
import com.google.gerrit.httpd.rpc.BaseServiceImplementation;
import com.google.gerrit.httpd.rpc.Handler;
import com.google.gerrit.reviewdb.Account;
@@ -39,6 +41,7 @@ import com.google.gerrit.server.account.AuthRequest;
import com.google.gerrit.server.account.ChangeUserName;
import com.google.gerrit.server.account.ClearPassword;
import com.google.gerrit.server.account.GeneratePassword;
import com.google.gerrit.server.account.GroupDetailFactory;
import com.google.gerrit.server.account.Realm;
import com.google.gerrit.server.config.AuthConfig;
import com.google.gerrit.server.contact.ContactStore;
@@ -58,6 +61,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Set;
@@ -82,6 +86,7 @@ class AccountSecurityImpl extends BaseServiceImplementation implements
private final DeleteExternalIds.Factory deleteExternalIdsFactory;
private final ExternalIdDetailFactory.Factory externalIdDetailFactory;
private final MyGroupsFactory.Factory myGroupsFactory;
private final GroupDetailFactory.Factory groupDetailFactory;
@Inject
AccountSecurityImpl(final Provider<ReviewDb> schema,
@@ -95,7 +100,8 @@ class AccountSecurityImpl extends BaseServiceImplementation implements
final ChangeUserName.CurrentUser changeUserNameFactory,
final DeleteExternalIds.Factory deleteExternalIdsFactory,
final ExternalIdDetailFactory.Factory externalIdDetailFactory,
final MyGroupsFactory.Factory myGroupsFactory) {
final MyGroupsFactory.Factory myGroupsFactory,
final GroupDetailFactory.Factory groupDetailFactory) {
super(schema, currentUser);
contactStore = cs;
authConfig = ac;
@@ -115,6 +121,7 @@ class AccountSecurityImpl extends BaseServiceImplementation implements
this.deleteExternalIdsFactory = deleteExternalIdsFactory;
this.externalIdDetailFactory = externalIdDetailFactory;
this.myGroupsFactory = myGroupsFactory;
this.groupDetailFactory = groupDetailFactory;
}
public void mySshKeys(final AsyncCallback<List<AccountSshKey>> callback) {
@@ -198,8 +205,17 @@ class AccountSecurityImpl extends BaseServiceImplementation implements
}
@Override
public void myGroups(final AsyncCallback<List<AccountGroup>> callback) {
myGroupsFactory.create().to(callback);
public void myGroups(final AsyncCallback<List<GroupDetail>> callback) {
run(callback, new Action<List<GroupDetail>>() {
public List<GroupDetail> run(final ReviewDb db) throws OrmException,
NoSuchGroupException, Failure {
List<GroupDetail> groupDetails = new ArrayList<GroupDetail>();
for(AccountGroup group : myGroupsFactory.create().call()) {
groupDetails.add(groupDetailFactory.create(group.getId()).call());
}
return groupDetails;
}
});
}
public void deleteExternalIds(final Set<AccountExternalId.Key> keys,

View File

@@ -91,7 +91,8 @@ class GroupAdminServiceImpl extends BaseServiceImplementation implements
public void visibleGroups(final AsyncCallback<GroupList> callback) {
run(callback, new Action<GroupList>() {
public GroupList run(ReviewDb db) throws OrmException {
public GroupList run(ReviewDb db) throws OrmException,
NoSuchGroupException {
final IdentifiedUser user = identifiedUser.get();
final List<AccountGroup> list;
if (user.getCapabilities().canAdministrateServer()) {
@@ -111,8 +112,12 @@ class GroupAdminServiceImpl extends BaseServiceImplementation implements
}
});
List<GroupDetail> l = new ArrayList<GroupDetail>();
for(AccountGroup group : list) {
l.add(groupDetailFactory.create(group.getId()).call());
}
GroupList res = new GroupList();
res.setGroups(list);
res.setGroups(l);
res.setCanCreateGroup(user.getCapabilities().canCreateGroup());
return res;
}

View File

@@ -41,7 +41,7 @@ class MyGroupsFactory extends Handler<List<AccountGroup>> {
}
@Override
public List<AccountGroup> call() throws Exception {
public List<AccountGroup> call() {
final Set<AccountGroup.UUID> effective = user.getEffectiveGroups();
final int cnt = effective.size();
final List<AccountGroup> groupList = new ArrayList<AccountGroup>(cnt);