/* | |
* Copyright 2011 gitblit.com. | |
* | |
* 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.gitblit.client; | |
import java.awt.BorderLayout; | |
import java.awt.FlowLayout; | |
import java.awt.Insets; | |
import java.awt.event.ActionEvent; | |
import java.awt.event.ActionListener; | |
import java.awt.event.KeyAdapter; | |
import java.awt.event.KeyEvent; | |
import java.awt.event.MouseAdapter; | |
import java.awt.event.MouseEvent; | |
import java.io.IOException; | |
import java.util.ArrayList; | |
import java.util.List; | |
import javax.swing.JButton; | |
import javax.swing.JLabel; | |
import javax.swing.JOptionPane; | |
import javax.swing.JPanel; | |
import javax.swing.JScrollPane; | |
import javax.swing.JTable; | |
import javax.swing.JTextField; | |
import javax.swing.RowFilter; | |
import javax.swing.event.ListSelectionEvent; | |
import javax.swing.event.ListSelectionListener; | |
import javax.swing.table.TableRowSorter; | |
import com.gitblit.Constants.RpcRequest; | |
import com.gitblit.models.TeamModel; | |
import com.gitblit.utils.StringUtils; | |
/** | |
* Users panel displays a list of user accounts and allows management of those | |
* accounts. | |
* | |
* @author James Moger | |
* | |
*/ | |
public abstract class TeamsPanel extends JPanel { | |
private static final long serialVersionUID = 1L; | |
private final GitblitClient gitblit; | |
private HeaderPanel header; | |
private JTable table; | |
private TeamsTableModel tableModel; | |
private TableRowSorter<TeamsTableModel> defaultSorter; | |
private JTextField filterTextfield; | |
public TeamsPanel(GitblitClient gitblit) { | |
super(); | |
this.gitblit = gitblit; | |
initialize(); | |
} | |
private void initialize() { | |
JButton refreshTeams = new JButton(Translation.get("gb.refresh")); | |
refreshTeams.addActionListener(new ActionListener() { | |
@Override | |
public void actionPerformed(ActionEvent e) { | |
refreshTeams(); | |
} | |
}); | |
JButton createTeam = new JButton(Translation.get("gb.create")); | |
createTeam.addActionListener(new ActionListener() { | |
@Override | |
public void actionPerformed(ActionEvent e) { | |
createTeam(); | |
} | |
}); | |
final JButton editTeam = new JButton(Translation.get("gb.edit")); | |
editTeam.setEnabled(false); | |
editTeam.addActionListener(new ActionListener() { | |
@Override | |
public void actionPerformed(ActionEvent e) { | |
editTeam(getSelectedTeams().get(0)); | |
} | |
}); | |
final JButton delTeam = new JButton(Translation.get("gb.delete")); | |
delTeam.setEnabled(false); | |
delTeam.addActionListener(new ActionListener() { | |
@Override | |
public void actionPerformed(ActionEvent e) { | |
deleteTeams(getSelectedTeams()); | |
} | |
}); | |
NameRenderer nameRenderer = new NameRenderer(); | |
tableModel = new TeamsTableModel(); | |
defaultSorter = new TableRowSorter<TeamsTableModel>(tableModel); | |
table = Utils.newTable(tableModel, Utils.DATE_FORMAT); | |
String name = table.getColumnName(TeamsTableModel.Columns.Name.ordinal()); | |
table.getColumn(name).setCellRenderer(nameRenderer); | |
int w = 125; | |
name = table.getColumnName(TeamsTableModel.Columns.Members.ordinal()); | |
table.getColumn(name).setMinWidth(w); | |
table.getColumn(name).setMaxWidth(w); | |
name = table.getColumnName(TeamsTableModel.Columns.Repositories.ordinal()); | |
table.getColumn(name).setMinWidth(w); | |
table.getColumn(name).setMaxWidth(w); | |
table.setRowSorter(defaultSorter); | |
table.getRowSorter().toggleSortOrder(TeamsTableModel.Columns.Name.ordinal()); | |
table.getSelectionModel().addListSelectionListener(new ListSelectionListener() { | |
@Override | |
public void valueChanged(ListSelectionEvent e) { | |
if (e.getValueIsAdjusting()) { | |
return; | |
} | |
boolean selected = table.getSelectedRow() > -1; | |
boolean singleSelection = table.getSelectedRows().length == 1; | |
editTeam.setEnabled(singleSelection && selected); | |
delTeam.setEnabled(selected); | |
} | |
}); | |
table.addMouseListener(new MouseAdapter() { | |
@Override | |
public void mouseClicked(MouseEvent e) { | |
if (e.getClickCount() == 2) { | |
editTeam(getSelectedTeams().get(0)); | |
} | |
} | |
}); | |
filterTextfield = new JTextField(); | |
filterTextfield.addActionListener(new ActionListener() { | |
@Override | |
public void actionPerformed(ActionEvent e) { | |
filterTeams(filterTextfield.getText()); | |
} | |
}); | |
filterTextfield.addKeyListener(new KeyAdapter() { | |
@Override | |
public void keyReleased(KeyEvent e) { | |
filterTeams(filterTextfield.getText()); | |
} | |
}); | |
JPanel teamFilterPanel = new JPanel(new BorderLayout(Utils.MARGIN, Utils.MARGIN)); | |
teamFilterPanel.add(new JLabel(Translation.get("gb.filter")), BorderLayout.WEST); | |
teamFilterPanel.add(filterTextfield, BorderLayout.CENTER); | |
JPanel teamTablePanel = new JPanel(new BorderLayout(Utils.MARGIN, Utils.MARGIN)); | |
teamTablePanel.add(teamFilterPanel, BorderLayout.NORTH); | |
teamTablePanel.add(new JScrollPane(table), BorderLayout.CENTER); | |
JPanel teamControls = new JPanel(new FlowLayout(FlowLayout.CENTER, 5, 0)); | |
teamControls.add(refreshTeams); | |
teamControls.add(createTeam); | |
teamControls.add(editTeam); | |
teamControls.add(delTeam); | |
setLayout(new BorderLayout(Utils.MARGIN, Utils.MARGIN)); | |
header = new HeaderPanel(Translation.get("gb.teams"), "users_16x16.png"); | |
add(header, BorderLayout.NORTH); | |
add(teamTablePanel, BorderLayout.CENTER); | |
add(teamControls, BorderLayout.SOUTH); | |
} | |
@Override | |
public void requestFocus() { | |
filterTextfield.requestFocus(); | |
} | |
@Override | |
public Insets getInsets() { | |
return Utils.INSETS; | |
} | |
protected abstract void updateUsersTable(); | |
protected void updateTable(boolean pack) { | |
tableModel.list.clear(); | |
tableModel.list.addAll(gitblit.getTeams()); | |
tableModel.fireTableDataChanged(); | |
header.setText(Translation.get("gb.teams") + " (" + gitblit.getTeams().size() + ")"); | |
if (pack) { | |
Utils.packColumns(table, Utils.MARGIN); | |
} | |
} | |
private void filterTeams(final String fragment) { | |
if (StringUtils.isEmpty(fragment)) { | |
table.setRowSorter(defaultSorter); | |
return; | |
} | |
RowFilter<TeamsTableModel, Object> containsFilter = new RowFilter<TeamsTableModel, Object>() { | |
@Override | |
public boolean include(Entry<? extends TeamsTableModel, ? extends Object> entry) { | |
for (int i = entry.getValueCount() - 1; i >= 0; i--) { | |
if (entry.getStringValue(i).toLowerCase().contains(fragment.toLowerCase())) { | |
return true; | |
} | |
} | |
return false; | |
} | |
}; | |
TableRowSorter<TeamsTableModel> sorter = new TableRowSorter<TeamsTableModel>(tableModel); | |
sorter.setRowFilter(containsFilter); | |
table.setRowSorter(sorter); | |
} | |
private List<TeamModel> getSelectedTeams() { | |
List<TeamModel> teams = new ArrayList<TeamModel>(); | |
for (int viewRow : table.getSelectedRows()) { | |
int modelRow = table.convertRowIndexToModel(viewRow); | |
TeamModel model = tableModel.list.get(modelRow); | |
teams.add(model); | |
} | |
return teams; | |
} | |
protected void refreshTeams() { | |
GitblitWorker worker = new GitblitWorker(TeamsPanel.this, RpcRequest.LIST_TEAMS) { | |
@Override | |
protected Boolean doRequest() throws IOException { | |
gitblit.refreshTeams(); | |
return true; | |
} | |
@Override | |
protected void onSuccess() { | |
updateTable(false); | |
} | |
}; | |
worker.execute(); | |
} | |
/** | |
* Displays the create team dialog and fires a SwingWorker to update the | |
* server, if appropriate. | |
* | |
*/ | |
protected void createTeam() { | |
EditTeamDialog dialog = new EditTeamDialog(gitblit.getProtocolVersion(), | |
gitblit.getSettings()); | |
dialog.setLocationRelativeTo(TeamsPanel.this); | |
dialog.setTeams(gitblit.getTeams()); | |
dialog.setRepositories(gitblit.getRepositories(), null); | |
dialog.setUsers(gitblit.getUsernames(), null); | |
dialog.setPreReceiveScripts(gitblit.getPreReceiveScriptsUnused(null), | |
gitblit.getPreReceiveScriptsInherited(null), null); | |
dialog.setPostReceiveScripts(gitblit.getPostReceiveScriptsUnused(null), | |
gitblit.getPostReceiveScriptsInherited(null), null); | |
dialog.setVisible(true); | |
final TeamModel newTeam = dialog.getTeam(); | |
if (newTeam == null) { | |
return; | |
} | |
GitblitWorker worker = new GitblitWorker(this, RpcRequest.CREATE_TEAM) { | |
@Override | |
protected Boolean doRequest() throws IOException { | |
boolean success = gitblit.createTeam(newTeam); | |
if (success) { | |
gitblit.refreshTeams(); | |
gitblit.refreshUsers(); | |
} | |
return success; | |
} | |
@Override | |
protected void onSuccess() { | |
updateTable(false); | |
updateUsersTable(); | |
} | |
@Override | |
protected void onFailure() { | |
showFailure("Failed to execute request \"{0}\" for team \"{1}\".", | |
getRequestType(), newTeam.name); | |
} | |
}; | |
worker.execute(); | |
} | |
/** | |
* Displays the edit team dialog and fires a SwingWorker to update the | |
* server, if appropriate. | |
* | |
* @param user | |
*/ | |
protected void editTeam(final TeamModel team) { | |
EditTeamDialog dialog = new EditTeamDialog(gitblit.getProtocolVersion(), team, | |
gitblit.getSettings()); | |
dialog.setLocationRelativeTo(TeamsPanel.this); | |
dialog.setTeams(gitblit.getTeams()); | |
dialog.setRepositories(gitblit.getRepositories(), team.getRepositoryPermissions()); | |
dialog.setUsers(gitblit.getUsernames(), team.users == null ? null : new ArrayList<String>( | |
team.users)); | |
dialog.setPreReceiveScripts(gitblit.getPreReceiveScriptsUnused(null), | |
gitblit.getPreReceiveScriptsInherited(null), team.preReceiveScripts); | |
dialog.setPostReceiveScripts(gitblit.getPostReceiveScriptsUnused(null), | |
gitblit.getPostReceiveScriptsInherited(null), team.postReceiveScripts); | |
dialog.setVisible(true); | |
final TeamModel revisedTeam = dialog.getTeam(); | |
if (revisedTeam == null) { | |
return; | |
} | |
GitblitWorker worker = new GitblitWorker(this, RpcRequest.EDIT_TEAM) { | |
@Override | |
protected Boolean doRequest() throws IOException { | |
boolean success = gitblit.updateTeam(team.name, revisedTeam); | |
if (success) { | |
gitblit.refreshTeams(); | |
gitblit.refreshUsers(); | |
} | |
return success; | |
} | |
@Override | |
protected void onSuccess() { | |
updateTable(false); | |
updateUsersTable(); | |
} | |
@Override | |
protected void onFailure() { | |
showFailure("Failed to execute request \"{0}\" for team \"{1}\".", | |
getRequestType(), team.name); | |
} | |
}; | |
worker.execute(); | |
} | |
protected void deleteTeams(final List<TeamModel> teams) { | |
if (teams == null || teams.size() == 0) { | |
return; | |
} | |
StringBuilder message = new StringBuilder("Delete the following teams?\n\n"); | |
for (TeamModel team : teams) { | |
message.append(team.name).append("\n"); | |
} | |
int result = JOptionPane.showConfirmDialog(TeamsPanel.this, message.toString(), | |
"Delete Teams?", JOptionPane.YES_NO_OPTION); | |
if (result == JOptionPane.YES_OPTION) { | |
GitblitWorker worker = new GitblitWorker(this, RpcRequest.DELETE_TEAM) { | |
@Override | |
protected Boolean doRequest() throws IOException { | |
boolean success = true; | |
for (TeamModel team : teams) { | |
success &= gitblit.deleteTeam(team); | |
} | |
if (success) { | |
gitblit.refreshTeams(); | |
gitblit.refreshUsers(); | |
} | |
return success; | |
} | |
@Override | |
protected void onSuccess() { | |
updateTable(false); | |
updateUsersTable(); | |
} | |
@Override | |
protected void onFailure() { | |
showFailure("Failed to delete specified teams!"); | |
} | |
}; | |
worker.execute(); | |
} | |
} | |
} |