Added some right-click functionality, and made dependencies safe.
This commit is contained in:
parent
134d2ede64
commit
a1d23b82ad
8
pom.xml
8
pom.xml
|
@ -30,12 +30,12 @@
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>commons-cli</groupId>
|
<groupId>commons-cli</groupId>
|
||||||
<artifactId>commons-cli</artifactId>
|
<artifactId>commons-cli</artifactId>
|
||||||
<version>RELEASE</version>
|
<version>1.4</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>commons-email</groupId>
|
<groupId>org.apache.commons</groupId>
|
||||||
<artifactId>commons-email</artifactId>
|
<artifactId>commons-email</artifactId>
|
||||||
<version>RELEASE</version>
|
<version>1.5</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.jetbrains</groupId>
|
<groupId>org.jetbrains</groupId>
|
||||||
|
@ -46,7 +46,7 @@
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.apache.httpcomponents</groupId>
|
<groupId>org.apache.httpcomponents</groupId>
|
||||||
<artifactId>httpclient</artifactId>
|
<artifactId>httpclient</artifactId>
|
||||||
<version>RELEASE</version>
|
<version>4.5.6</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<!-- Github API Object Library -->
|
<!-- Github API Object Library -->
|
||||||
<dependency>
|
<dependency>
|
||||||
|
|
|
@ -251,7 +251,7 @@ public class GithubManager {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
team.setRepository(repo);
|
team.setRepositoryName(repo.getName());
|
||||||
team.setTaTeam(taTeam);
|
team.setTaTeam(taTeam);
|
||||||
|
|
||||||
this.protectMasterBranch(repo, taTeam.getGithubTeam());
|
this.protectMasterBranch(repo, taTeam.getGithubTeam());
|
||||||
|
@ -339,7 +339,7 @@ public class GithubManager {
|
||||||
GHUser user = this.github.getUser(student.getGithubUsername());
|
GHUser user = this.github.getUser(student.getGithubUsername());
|
||||||
|
|
||||||
this.addCollaboratorToRepo(user, assignmentsRepo);
|
this.addCollaboratorToRepo(user, assignmentsRepo);
|
||||||
this.addCollaboratorToRepo(user, team.getRepository());
|
this.addCollaboratorToRepo(user, this.organization.getRepository(team.getRepositoryName()));
|
||||||
}
|
}
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
logger.severe("Could not add students as collaborators to assignments or their repo.\n" + team);
|
logger.severe("Could not add students as collaborators to assignments or their repo.\n" + team);
|
||||||
|
|
|
@ -21,25 +21,25 @@ public abstract class Person extends BaseEntity implements Detailable {
|
||||||
/**
|
/**
|
||||||
* The unique identification number for this person. (P- or S-Number)
|
* The unique identification number for this person. (P- or S-Number)
|
||||||
*/
|
*/
|
||||||
@Column(name="number")
|
@Column(name="number", nullable = false)
|
||||||
protected int number;
|
protected int number;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The person's first and last name.
|
* The person's first and last name.
|
||||||
*/
|
*/
|
||||||
@Column(name="name")
|
@Column(name="name", nullable = false)
|
||||||
protected String name;
|
protected String name;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The person's email address.
|
* The person's email address.
|
||||||
*/
|
*/
|
||||||
@Column(name="email_address")
|
@Column(name="email_address", nullable = false)
|
||||||
protected String emailAddress;
|
protected String emailAddress;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The person's github username.
|
* The person's github username.
|
||||||
*/
|
*/
|
||||||
@Column(name="github_username")
|
@Column(name="github_username", nullable = false)
|
||||||
protected String githubUsername;
|
protected String githubUsername;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -1,12 +1,13 @@
|
||||||
package nl.andrewlalis.model;
|
package nl.andrewlalis.model;
|
||||||
|
|
||||||
import org.kohsuke.github.GHRepository;
|
import nl.andrewlalis.util.Pair;
|
||||||
|
|
||||||
|
import javax.persistence.Column;
|
||||||
import javax.persistence.Entity;
|
import javax.persistence.Entity;
|
||||||
import javax.persistence.ManyToOne;
|
import javax.persistence.ManyToOne;
|
||||||
import javax.persistence.Table;
|
import javax.persistence.Table;
|
||||||
import javax.persistence.Transient;
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents one or more students' collective information.
|
* Represents one or more students' collective information.
|
||||||
|
@ -18,8 +19,8 @@ public class StudentTeam extends Team {
|
||||||
/**
|
/**
|
||||||
* The repository belonging to this team.
|
* The repository belonging to this team.
|
||||||
*/
|
*/
|
||||||
@Transient
|
@Column(name = "repository_name", unique = true)
|
||||||
private GHRepository repository;
|
private String repositoryName;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The TATeam responsible for this student team.
|
* The TATeam responsible for this student team.
|
||||||
|
@ -97,12 +98,12 @@ public class StudentTeam extends Team {
|
||||||
return sb.toString();
|
return sb.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
public GHRepository getRepository() {
|
public String getRepositoryName() {
|
||||||
return this.repository;
|
return this.repositoryName;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setRepository(GHRepository repo) {
|
public void setRepositoryName(String repositoryName) {
|
||||||
this.repository = repo;
|
this.repositoryName = repositoryName;
|
||||||
}
|
}
|
||||||
|
|
||||||
public TATeam getTaTeam() {
|
public TATeam getTaTeam() {
|
||||||
|
@ -117,4 +118,17 @@ public class StudentTeam extends Team {
|
||||||
public String getDetailName() {
|
public String getDetailName() {
|
||||||
return this.generateRepoDescription();
|
return this.generateRepoDescription();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Pair<String, String>> getDetailPairs() {
|
||||||
|
List<Pair<String, String>> pairs = super.getDetailPairs();
|
||||||
|
pairs.add(new Pair<>("Repository Name", this.getRepositoryName()));
|
||||||
|
String taTeamName = "None";
|
||||||
|
if (this.getTaTeam() != null) {
|
||||||
|
taTeamName = this.getTaTeam().getDetailName();
|
||||||
|
}
|
||||||
|
pairs.add(new Pair<>("TA Team", taTeamName));
|
||||||
|
|
||||||
|
return pairs;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,42 @@
|
||||||
|
package nl.andrewlalis.ui.control.listeners.management_view;
|
||||||
|
|
||||||
|
import javax.swing.*;
|
||||||
|
import javax.swing.event.PopupMenuEvent;
|
||||||
|
import javax.swing.event.PopupMenuListener;
|
||||||
|
import java.awt.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This listener, when added to a JPopupMenu, will select the clicked row when a user right-clicks on the table.
|
||||||
|
*/
|
||||||
|
public class PopupSelector implements PopupMenuListener {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The table on which to select rows.
|
||||||
|
*/
|
||||||
|
private JTable table;
|
||||||
|
|
||||||
|
public PopupSelector(JTable table) {
|
||||||
|
this.table = table;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void popupMenuWillBecomeVisible(PopupMenuEvent popupMenuEvent) {
|
||||||
|
JPopupMenu popupMenu = (JPopupMenu) popupMenuEvent.getSource();
|
||||||
|
SwingUtilities.invokeLater(() -> {
|
||||||
|
int rowAtPoint = table.rowAtPoint(SwingUtilities.convertPoint(popupMenu, new Point(0, 0), table));
|
||||||
|
if (rowAtPoint > -1) {
|
||||||
|
table.setRowSelectionInterval(rowAtPoint, rowAtPoint);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void popupMenuWillBecomeInvisible(PopupMenuEvent popupMenuEvent) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void popupMenuCanceled(PopupMenuEvent popupMenuEvent) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,39 @@
|
||||||
|
package nl.andrewlalis.ui.control.listeners.management_view;
|
||||||
|
|
||||||
|
import javax.swing.*;
|
||||||
|
import java.awt.event.ActionListener;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This abstract class defines listeners which listen to tables, that is, a table row is clicked on in the table, and
|
||||||
|
* that is passed to children.
|
||||||
|
*/
|
||||||
|
public abstract class TableRowListener implements ActionListener {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The table of which to get the row.
|
||||||
|
*/
|
||||||
|
private JTable table;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a table row listener.
|
||||||
|
* @param table The table on which to get selected rows.
|
||||||
|
*/
|
||||||
|
public TableRowListener(JTable table) {
|
||||||
|
this.table = table;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The selected row.
|
||||||
|
*/
|
||||||
|
protected final int getSelectedRow() {
|
||||||
|
return this.table.getSelectedRow();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The table that this listener is attached to.
|
||||||
|
*/
|
||||||
|
protected final JTable getTable() {
|
||||||
|
return this.table;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,28 @@
|
||||||
|
package nl.andrewlalis.ui.control.listeners.management_view.student_actions;
|
||||||
|
|
||||||
|
import nl.andrewlalis.ui.control.listeners.management_view.TableRowListener;
|
||||||
|
import nl.andrewlalis.ui.view.table_models.StudentTableModel;
|
||||||
|
|
||||||
|
import javax.swing.*;
|
||||||
|
import java.awt.event.ActionEvent;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Listens for when the user intends to remove a selected student from the course entirely. This entails a few things:
|
||||||
|
* 1. Remove them from any team they are in.
|
||||||
|
* 2. Archive any repository that is empty as a result of removing them.
|
||||||
|
* 3. Remove the student from the list of students.
|
||||||
|
* (This should not actually remove the record, just set it as removed.)
|
||||||
|
*/
|
||||||
|
public class RemoveFromCourseListener extends TableRowListener {
|
||||||
|
|
||||||
|
public RemoveFromCourseListener(JTable table) {
|
||||||
|
super(table);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void actionPerformed(ActionEvent actionEvent) {
|
||||||
|
StudentTableModel model = (StudentTableModel) this.getTable().getModel();
|
||||||
|
|
||||||
|
System.out.println(model.getStudentAt(this.getSelectedRow()));
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,31 @@
|
||||||
|
package nl.andrewlalis.ui.control.listeners.management_view.student_actions;
|
||||||
|
|
||||||
|
import nl.andrewlalis.model.Student;
|
||||||
|
import nl.andrewlalis.model.StudentTeam;
|
||||||
|
import nl.andrewlalis.ui.control.listeners.management_view.TableRowListener;
|
||||||
|
import nl.andrewlalis.ui.view.dialogs.TeamChooserDialog;
|
||||||
|
import nl.andrewlalis.ui.view.table_models.StudentTableModel;
|
||||||
|
|
||||||
|
import javax.swing.*;
|
||||||
|
import java.awt.event.ActionEvent;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Listens for when the user wishes to set the team of a certain student. This should do the following:
|
||||||
|
* 1. User selects team to set student to, or chooses to create a new team.
|
||||||
|
* 2. StudentTeam object is created or modified.
|
||||||
|
* 3. The repository is updated automatically.
|
||||||
|
*/
|
||||||
|
public class SetTeamListener extends TableRowListener {
|
||||||
|
|
||||||
|
public SetTeamListener(JTable table) {
|
||||||
|
super(table);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void actionPerformed(ActionEvent actionEvent) {
|
||||||
|
StudentTableModel model = (StudentTableModel) this.getTable().getModel();
|
||||||
|
Student student = model.getStudentAt(this.getSelectedRow());
|
||||||
|
|
||||||
|
StudentTeam chosenTeam = (StudentTeam) new TeamChooserDialog(SwingUtilities.getWindowAncestor(this.getTable())).getSelectedTeam();
|
||||||
|
}
|
||||||
|
}
|
|
@ -28,6 +28,11 @@ public abstract class AbstractView extends JFrame {
|
||||||
*/
|
*/
|
||||||
private List<AbstractView> parentViews;
|
private List<AbstractView> parentViews;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The image icon for all abstract views.
|
||||||
|
*/
|
||||||
|
private static final ImageIcon imageIcon = new ImageIcon(AbstractView.class.getResource("/image/icon.png"));
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initializes the view by packing the content pane as it is defined by any child, and setting some generic swing
|
* Initializes the view by packing the content pane as it is defined by any child, and setting some generic swing
|
||||||
* values.
|
* values.
|
||||||
|
@ -42,6 +47,7 @@ public abstract class AbstractView extends JFrame {
|
||||||
this.githubManager = githubManager;
|
this.githubManager = githubManager;
|
||||||
this.childViews = new ArrayList<>();
|
this.childViews = new ArrayList<>();
|
||||||
this.parentViews = new ArrayList<>();
|
this.parentViews = new ArrayList<>();
|
||||||
|
this.setIconImage(imageIcon.getImage());
|
||||||
this.setContentPane(this.buildContentPane());
|
this.setContentPane(this.buildContentPane());
|
||||||
this.setDefaultCloseOperation(defaultCloseOperation);
|
this.setDefaultCloseOperation(defaultCloseOperation);
|
||||||
if (preferredSize != null) {
|
if (preferredSize != null) {
|
||||||
|
|
|
@ -3,6 +3,8 @@ package nl.andrewlalis.ui.view;
|
||||||
import nl.andrewlalis.git_api.GithubManager;
|
import nl.andrewlalis.git_api.GithubManager;
|
||||||
import nl.andrewlalis.model.database.DbHelper;
|
import nl.andrewlalis.model.database.DbHelper;
|
||||||
import nl.andrewlalis.model.database.DbUtil;
|
import nl.andrewlalis.model.database.DbUtil;
|
||||||
|
import nl.andrewlalis.ui.control.listeners.management_view.PopupSelector;
|
||||||
|
import nl.andrewlalis.ui.control.listeners.management_view.student_actions.RemoveFromCourseListener;
|
||||||
import nl.andrewlalis.ui.view.components.DetailPanel;
|
import nl.andrewlalis.ui.view.components.DetailPanel;
|
||||||
import nl.andrewlalis.ui.view.table_models.StudentTableModel;
|
import nl.andrewlalis.ui.view.table_models.StudentTableModel;
|
||||||
import nl.andrewlalis.ui.view.table_models.StudentTeamTableModel;
|
import nl.andrewlalis.ui.view.table_models.StudentTeamTableModel;
|
||||||
|
@ -145,6 +147,13 @@ public class ManagementView extends AbstractView {
|
||||||
table.getSelectionModel().addListSelectionListener(listSelectionEvent -> {
|
table.getSelectionModel().addListSelectionListener(listSelectionEvent -> {
|
||||||
detailPanel.setDetailableEntity(studentsModel.getStudentAt(table.getSelectedRow()));
|
detailPanel.setDetailableEntity(studentsModel.getStudentAt(table.getSelectedRow()));
|
||||||
});
|
});
|
||||||
|
JPopupMenu menu = new JPopupMenu("Menu");
|
||||||
|
JMenuItem removeItem = new JMenuItem("Remove from course");
|
||||||
|
removeItem.addActionListener(new RemoveFromCourseListener(table));
|
||||||
|
menu.add(removeItem);
|
||||||
|
menu.addPopupMenuListener(new PopupSelector(table));
|
||||||
|
table.setComponentPopupMenu(menu);
|
||||||
|
|
||||||
return this.buildGenericTablePanel(table);
|
return this.buildGenericTablePanel(table);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
package nl.andrewlalis.ui.view.dialogs;
|
||||||
|
|
||||||
|
import nl.andrewlalis.model.Team;
|
||||||
|
|
||||||
|
import javax.swing.*;
|
||||||
|
import java.awt.*;
|
||||||
|
|
||||||
|
public class TeamChooserDialog extends JDialog {
|
||||||
|
|
||||||
|
public TeamChooserDialog(Window parent) {
|
||||||
|
super(parent);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Team getSelectedTeam() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -21,7 +21,7 @@ public class StudentTeamTableModel extends AbstractTableModel {
|
||||||
* The column headers for this model. In addition to these headers, this model will dynamically create headers for
|
* The column headers for this model. In addition to these headers, this model will dynamically create headers for
|
||||||
* each additional student to be listed in the table.
|
* each additional student to be listed in the table.
|
||||||
*/
|
*/
|
||||||
private final String[] staticColumns = {"Number", "Member Count"};
|
private final String[] staticColumns = {"Number", "Repository Name", "TA Team"};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Dynamic columns which are generated depending on the teams.
|
* Dynamic columns which are generated depending on the teams.
|
||||||
|
@ -90,7 +90,9 @@ public class StudentTeamTableModel extends AbstractTableModel {
|
||||||
case 0:
|
case 0:
|
||||||
return team.getId();
|
return team.getId();
|
||||||
case 1:
|
case 1:
|
||||||
return team.memberCount();
|
return (team.getRepositoryName() == null) ? "None" : team.getRepositoryName();
|
||||||
|
case 2:
|
||||||
|
return (team.getTaTeam() == null) ? "None" : team.getTaTeam().getDetailName();
|
||||||
default:
|
default:
|
||||||
return this.getMemberInColumn(team, i1);
|
return this.getMemberInColumn(team, i1);
|
||||||
}
|
}
|
||||||
|
@ -135,8 +137,9 @@ public class StudentTeamTableModel extends AbstractTableModel {
|
||||||
this.columns = new String[this.staticColumns.length + maxMembers];
|
this.columns = new String[this.staticColumns.length + maxMembers];
|
||||||
this.columns[0] = this.staticColumns[0];
|
this.columns[0] = this.staticColumns[0];
|
||||||
this.columns[1] = this.staticColumns[1];
|
this.columns[1] = this.staticColumns[1];
|
||||||
|
this.columns[2] = this.staticColumns[2];
|
||||||
for (int i = 0; i < maxMembers; i++) {
|
for (int i = 0; i < maxMembers; i++) {
|
||||||
this.columns[i + 2] = "Member " + (i + 1);
|
this.columns[i + this.staticColumns.length] = "Member " + (i + 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue