blob: dd76875200acc4dc1cf056dce2a02cd55e07ea0e [file] [log] [blame]
// Copyright (C) 2008 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.admin;
import com.google.gerrit.client.Gerrit;
import com.google.gerrit.client.rpc.GerritCallback;
import com.google.gerrit.client.rpc.ScreenLoadCallback;
import com.google.gerrit.client.ui.AccountDashboardLink;
import com.google.gerrit.client.ui.AccountGroupSuggestOracle;
import com.google.gerrit.client.ui.AccountScreen;
import com.google.gerrit.client.ui.AddMemberBox;
import com.google.gerrit.client.ui.FancyFlexTable;
import com.google.gerrit.client.ui.SmallHeading;
import com.google.gerrit.client.ui.TextSaveButtonListener;
import com.google.gerrit.common.data.AccountInfoCache;
import com.google.gerrit.common.data.GroupDetail;
import com.google.gerrit.reviewdb.Account;
import com.google.gerrit.reviewdb.AccountGroup;
import com.google.gerrit.reviewdb.AccountGroupMember;
import com.google.gwt.event.dom.client.ChangeEvent;
import com.google.gwt.event.dom.client.ChangeHandler;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.KeyCodes;
import com.google.gwt.event.dom.client.KeyPressEvent;
import com.google.gwt.event.dom.client.KeyPressHandler;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.CheckBox;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.Grid;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.Panel;
import com.google.gwt.user.client.ui.SuggestBox;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.FlexTable.FlexCellFormatter;
import com.google.gwt.user.client.ui.HTMLTable.CellFormatter;
import com.google.gwtexpui.globalkey.client.NpTextArea;
import com.google.gwtexpui.globalkey.client.NpTextBox;
import com.google.gwtjsonrpc.client.VoidResult;
import java.util.HashSet;
import java.util.List;
public class AccountGroupScreen extends AccountScreen {
private final AccountGroup.Id groupId;
private AccountInfoCache accounts = AccountInfoCache.empty();
private MemberTable members;
private NpTextBox groupNameTxt;
private Button saveName;
private NpTextBox ownerTxtBox;
private SuggestBox ownerTxt;
private Button saveOwner;
private NpTextArea descTxt;
private Button saveDesc;
private Label typeSystem;
private ListBox typeSelect;
private Button saveType;
private Panel memberPanel;
private AddMemberBox addMemberBox;
private Button delMember;
private Panel externalPanel;
private Label externalName;
private NpTextBox externalNameFilter;
private Button externalNameSearch;
private Grid externalMatches;
public AccountGroupScreen(final AccountGroup.Id toShow) {
groupId = toShow;
}
@Override
protected void onLoad() {
super.onLoad();
Util.GROUP_SVC.groupDetail(groupId, new ScreenLoadCallback<GroupDetail>(
this) {
@Override
protected void preDisplay(final GroupDetail result) {
display(result);
}
});
}
@Override
protected void onInitUI() {
super.onInitUI();
initName();
initOwner();
initDescription();
initGroupType();
initMemberList();
initExternal();
}
private void initName() {
final VerticalPanel groupNamePanel = new VerticalPanel();
groupNameTxt = new NpTextBox();
groupNameTxt.setVisibleLength(60);
groupNamePanel.add(groupNameTxt);
saveName = new Button(Util.C.buttonRenameGroup());
saveName.setEnabled(false);
saveName.addClickHandler(new ClickHandler() {
@Override
public void onClick(final ClickEvent event) {
final String newName = groupNameTxt.getText().trim();
Util.GROUP_SVC.renameGroup(groupId, newName,
new GerritCallback<VoidResult>() {
public void onSuccess(final VoidResult result) {
saveName.setEnabled(false);
setPageTitle(Util.M.group(newName));
}
});
}
});
groupNamePanel.add(saveName);
add(groupNamePanel);
new TextSaveButtonListener(groupNameTxt, saveName);
}
private void initOwner() {
final VerticalPanel ownerPanel = new VerticalPanel();
ownerPanel.add(new SmallHeading(Util.C.headingOwner()));
ownerTxtBox = new NpTextBox();
ownerTxtBox.setVisibleLength(60);
ownerTxt = new SuggestBox(new AccountGroupSuggestOracle(), ownerTxtBox);
ownerPanel.add(ownerTxt);
saveOwner = new Button(Util.C.buttonChangeGroupOwner());
saveOwner.setEnabled(false);
saveOwner.addClickHandler(new ClickHandler() {
@Override
public void onClick(final ClickEvent event) {
final String newOwner = ownerTxt.getText().trim();
if (newOwner.length() > 0) {
Util.GROUP_SVC.changeGroupOwner(groupId, newOwner,
new GerritCallback<VoidResult>() {
public void onSuccess(final VoidResult result) {
saveOwner.setEnabled(false);
}
});
}
}
});
ownerPanel.add(saveOwner);
add(ownerPanel);
new TextSaveButtonListener(ownerTxtBox, saveOwner);
}
private void initDescription() {
final VerticalPanel vp = new VerticalPanel();
vp.add(new SmallHeading(Util.C.headingDescription()));
descTxt = new NpTextArea();
descTxt.setVisibleLines(6);
descTxt.setCharacterWidth(60);
vp.add(descTxt);
saveDesc = new Button(Util.C.buttonSaveDescription());
saveDesc.setEnabled(false);
saveDesc.addClickHandler(new ClickHandler() {
@Override
public void onClick(final ClickEvent event) {
final String txt = descTxt.getText().trim();
Util.GROUP_SVC.changeGroupDescription(groupId, txt,
new GerritCallback<VoidResult>() {
public void onSuccess(final VoidResult result) {
saveDesc.setEnabled(false);
}
});
}
});
vp.add(saveDesc);
add(vp);
new TextSaveButtonListener(descTxt, saveDesc);
}
private void initGroupType() {
typeSystem = new Label(Util.C.groupType_SYSTEM());
typeSelect = new ListBox();
typeSelect.addItem(Util.C.groupType_INTERNAL(), AccountGroup.Type.INTERNAL.name());
typeSelect.addItem(Util.C.groupType_LDAP(), AccountGroup.Type.LDAP.name());
typeSelect.addChangeHandler(new ChangeHandler() {
@Override
public void onChange(ChangeEvent event) {
saveType.setEnabled(true);
}
});
saveType = new Button(Util.C.buttonChangeGroupType());
saveType.setEnabled(false);
saveType.addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
onSaveType();
}
});
switch (Gerrit.getConfig().getAuthType()) {
case HTTP_LDAP:
case LDAP:
case LDAP_BIND:
break;
default:
return;
}
final VerticalPanel fp = new VerticalPanel();
fp.add(new SmallHeading(Util.C.headingGroupType()));
fp.add(typeSystem);
fp.add(typeSelect);
fp.add(saveType);
add(fp);
}
private void initMemberList() {
addMemberBox = new AddMemberBox();
addMemberBox.addClickHandler(new ClickHandler() {
@Override
public void onClick(final ClickEvent event) {
doAddNew();
}
});
members = new MemberTable();
delMember = new Button(Util.C.buttonDeleteGroupMembers());
delMember.addClickHandler(new ClickHandler() {
@Override
public void onClick(final ClickEvent event) {
members.deleteChecked();
}
});
memberPanel = new FlowPanel();
memberPanel.add(new SmallHeading(Util.C.headingMembers()));
memberPanel.add(addMemberBox);
memberPanel.add(members);
memberPanel.add(delMember);
add(memberPanel);
}
private void initExternal() {
externalName = new Label();
externalNameFilter = new NpTextBox();
externalNameFilter.setVisibleLength(30);
externalNameFilter.addKeyPressHandler(new KeyPressHandler() {
@Override
public void onKeyPress(final KeyPressEvent event) {
if (event.getCharCode() == KeyCodes.KEY_ENTER) {
doExternalSearch();
}
}
});
externalNameSearch = new Button(Gerrit.C.searchButton());
externalNameSearch.addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
doExternalSearch();
}
});
externalMatches = new Grid();
externalMatches.setStyleName(Gerrit.RESOURCES.css().infoTable());
externalMatches.setVisible(false);
final FlowPanel searchLine = new FlowPanel();
searchLine.add(externalNameFilter);
searchLine.add(externalNameSearch);
externalPanel = new VerticalPanel();
externalPanel.add(new SmallHeading(Util.C.headingExternalGroup()));
externalPanel.add(externalName);
externalPanel.add(searchLine);
externalPanel.add(externalMatches);
add(externalPanel);
}
private void setType(final AccountGroup.Type newType) {
final boolean system = newType == AccountGroup.Type.SYSTEM;
typeSystem.setVisible(system);
typeSelect.setVisible(!system);
saveType.setVisible(!system);
memberPanel.setVisible(newType == AccountGroup.Type.INTERNAL);
externalPanel.setVisible(newType == AccountGroup.Type.LDAP);
externalNameFilter.setText(groupNameTxt.getText());
if (!system) {
for (int i = 0; i < typeSelect.getItemCount(); i++) {
if (newType.name().equals(typeSelect.getValue(i))) {
typeSelect.setSelectedIndex(i);
break;
}
}
}
saveType.setEnabled(false);
}
private void onSaveType() {
final int idx = typeSelect.getSelectedIndex();
final AccountGroup.Type newType =
AccountGroup.Type.valueOf(typeSelect.getValue(idx));
typeSelect.setEnabled(false);
saveType.setEnabled(false);
Util.GROUP_SVC.changeGroupType(groupId, newType,
new GerritCallback<VoidResult>() {
@Override
public void onSuccess(VoidResult result) {
typeSelect.setEnabled(true);
setType(newType);
}
@Override
public void onFailure(Throwable caught) {
typeSelect.setEnabled(true);
saveType.setEnabled(true);
super.onFailure(caught);
}
});
}
private void doExternalSearch() {
externalNameFilter.setEnabled(false);
externalNameSearch.setEnabled(false);
Util.GROUP_SVC.searchExternalGroups(externalNameFilter.getText(),
new GerritCallback<List<AccountGroup.ExternalNameKey>>() {
@Override
public void onSuccess(List<AccountGroup.ExternalNameKey> result) {
final CellFormatter fmt = externalMatches.getCellFormatter();
if (result.isEmpty()) {
externalMatches.resize(1, 1);
externalMatches.setText(0, 0, Util.C.errorNoMatchingGroups());
fmt.setStyleName(0, 0, Gerrit.RESOURCES.css().header());
return;
}
externalMatches.resize(1 + result.size(), 2);
externalMatches.setText(0, 0, Util.C.columnGroupName());
externalMatches.setText(0, 1, "");
fmt.setStyleName(0, 0, Gerrit.RESOURCES.css().header());
fmt.setStyleName(0, 1, Gerrit.RESOURCES.css().header());
for (int row = 0; row < result.size(); row++) {
final AccountGroup.ExternalNameKey key = result.get(row);
final Button b = new Button(Util.C.buttonSelectGroup());
b.addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
setExternalGroup(key);
}
});
externalMatches.setText(1 + row, 0, key.get());
externalMatches.setWidget(1 + row, 1, b);
fmt.setStyleName(1 + row, 1, Gerrit.RESOURCES.css().rightmost());
}
externalMatches.setVisible(true);
externalNameFilter.setEnabled(true);
externalNameSearch.setEnabled(true);
}
@Override
public void onFailure(Throwable caught) {
externalNameFilter.setEnabled(true);
externalNameSearch.setEnabled(true);
super.onFailure(caught);
}
});
}
private void setExternalGroup(final AccountGroup.ExternalNameKey key) {
externalMatches.setVisible(false);
Util.GROUP_SVC.changeExternalGroup(groupId, key,
new GerritCallback<VoidResult>() {
@Override
public void onSuccess(VoidResult result) {
externalName.setText(key.get());
}
@Override
public void onFailure(Throwable caught) {
externalMatches.setVisible(true);
super.onFailure(caught);
}
});
}
private void display(final GroupDetail result) {
final AccountGroup group = result.group;
setPageTitle(Util.M.group(group.getName()));
groupNameTxt.setText(group.getName());
if (result.ownerGroup != null) {
ownerTxt.setText(result.ownerGroup.getName());
} else {
ownerTxt.setText(Util.M.deletedGroup(group.getOwnerGroupId().get()));
}
descTxt.setText(group.getDescription());
switch (group.getType()) {
case INTERNAL:
accounts = result.accounts;
members.display(result.members);
break;
case LDAP:
externalName.setText(group.getExternalNameKey() != null ? group
.getExternalNameKey().get() : Util.C.noGroupSelected());
break;
}
setType(group.getType());
}
void doAddNew() {
final String nameEmail = addMemberBox.getText();
if (nameEmail.length() == 0) {
return;
}
addMemberBox.setEnabled(false);
Util.GROUP_SVC.addGroupMember(groupId, nameEmail,
new GerritCallback<GroupDetail>() {
public void onSuccess(final GroupDetail result) {
addMemberBox.setEnabled(true);
addMemberBox.setText("");
if (result.accounts != null && result.members != null) {
accounts.merge(result.accounts);
members.display(result.members);
}
}
@Override
public void onFailure(final Throwable caught) {
addMemberBox.setEnabled(true);
super.onFailure(caught);
}
});
}
private class MemberTable extends FancyFlexTable<AccountGroupMember> {
MemberTable() {
table.setText(0, 2, Util.C.columnMember());
table.setText(0, 3, Util.C.columnEmailAddress());
final FlexCellFormatter fmt = table.getFlexCellFormatter();
fmt.addStyleName(0, 1, Gerrit.RESOURCES.css().iconHeader());
fmt.addStyleName(0, 2, Gerrit.RESOURCES.css().dataHeader());
fmt.addStyleName(0, 3, Gerrit.RESOURCES.css().dataHeader());
}
void deleteChecked() {
final HashSet<AccountGroupMember.Key> ids =
new HashSet<AccountGroupMember.Key>();
for (int row = 1; row < table.getRowCount(); row++) {
final AccountGroupMember k = getRowItem(row);
if (k != null && ((CheckBox) table.getWidget(row, 1)).getValue()) {
ids.add(k.getKey());
}
}
if (!ids.isEmpty()) {
Util.GROUP_SVC.deleteGroupMembers(groupId, ids,
new GerritCallback<VoidResult>() {
public void onSuccess(final VoidResult result) {
for (int row = 1; row < table.getRowCount();) {
final AccountGroupMember k = getRowItem(row);
if (k != null && ids.contains(k.getKey())) {
table.removeRow(row);
} else {
row++;
}
}
}
});
}
}
void insertMember(final AccountGroupMember k) {
final int row = table.getRowCount();
table.insertRow(row);
applyDataRowStyle(row);
populate(row, k);
}
void display(final List<AccountGroupMember> result) {
while (1 < table.getRowCount())
table.removeRow(table.getRowCount() - 1);
for (final AccountGroupMember k : result) {
final int row = table.getRowCount();
table.insertRow(row);
applyDataRowStyle(row);
populate(row, k);
}
}
void populate(final int row, final AccountGroupMember k) {
final Account.Id accountId = k.getAccountId();
table.setWidget(row, 1, new CheckBox());
table.setWidget(row, 2, AccountDashboardLink.link(accounts, accountId));
table.setText(row, 3, accounts.get(accountId).getPreferredEmail());
final FlexCellFormatter fmt = table.getFlexCellFormatter();
fmt.addStyleName(row, 1, Gerrit.RESOURCES.css().iconCell());
fmt.addStyleName(row, 2, Gerrit.RESOURCES.css().dataCell());
fmt.addStyleName(row, 3, Gerrit.RESOURCES.css().dataCell());
setRowItem(row, k);
}
}
}