diff --git a/pom.xml b/pom.xml
index 18af176..a6b89a7 100644
--- a/pom.xml
+++ b/pom.xml
@@ -30,12 +30,12 @@
commons-cli
commons-cli
- RELEASE
+ 1.4
- commons-email
+ org.apache.commons
commons-email
- RELEASE
+ 1.5
org.jetbrains
@@ -46,7 +46,7 @@
org.apache.httpcomponents
httpclient
- RELEASE
+ 4.5.6
diff --git a/src/main/java/nl/andrewlalis/git_api/GithubManager.java b/src/main/java/nl/andrewlalis/git_api/GithubManager.java
index 1f7c2a3..fe15ce7 100644
--- a/src/main/java/nl/andrewlalis/git_api/GithubManager.java
+++ b/src/main/java/nl/andrewlalis/git_api/GithubManager.java
@@ -251,7 +251,7 @@ public class GithubManager {
return;
}
- team.setRepository(repo);
+ team.setRepositoryName(repo.getName());
team.setTaTeam(taTeam);
this.protectMasterBranch(repo, taTeam.getGithubTeam());
@@ -339,7 +339,7 @@ public class GithubManager {
GHUser user = this.github.getUser(student.getGithubUsername());
this.addCollaboratorToRepo(user, assignmentsRepo);
- this.addCollaboratorToRepo(user, team.getRepository());
+ this.addCollaboratorToRepo(user, this.organization.getRepository(team.getRepositoryName()));
}
} catch (IOException e) {
logger.severe("Could not add students as collaborators to assignments or their repo.\n" + team);
diff --git a/src/main/java/nl/andrewlalis/model/Person.java b/src/main/java/nl/andrewlalis/model/Person.java
index 10b2488..d374761 100644
--- a/src/main/java/nl/andrewlalis/model/Person.java
+++ b/src/main/java/nl/andrewlalis/model/Person.java
@@ -21,25 +21,25 @@ public abstract class Person extends BaseEntity implements Detailable {
/**
* The unique identification number for this person. (P- or S-Number)
*/
- @Column(name="number")
+ @Column(name="number", nullable = false)
protected int number;
/**
* The person's first and last name.
*/
- @Column(name="name")
+ @Column(name="name", nullable = false)
protected String name;
/**
* The person's email address.
*/
- @Column(name="email_address")
+ @Column(name="email_address", nullable = false)
protected String emailAddress;
/**
* The person's github username.
*/
- @Column(name="github_username")
+ @Column(name="github_username", nullable = false)
protected String githubUsername;
/**
diff --git a/src/main/java/nl/andrewlalis/model/StudentTeam.java b/src/main/java/nl/andrewlalis/model/StudentTeam.java
index 232cd0b..c545771 100644
--- a/src/main/java/nl/andrewlalis/model/StudentTeam.java
+++ b/src/main/java/nl/andrewlalis/model/StudentTeam.java
@@ -1,12 +1,13 @@
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.ManyToOne;
import javax.persistence.Table;
-import javax.persistence.Transient;
import java.util.Arrays;
+import java.util.List;
/**
* Represents one or more students' collective information.
@@ -18,8 +19,8 @@ public class StudentTeam extends Team {
/**
* The repository belonging to this team.
*/
- @Transient
- private GHRepository repository;
+ @Column(name = "repository_name", unique = true)
+ private String repositoryName;
/**
* The TATeam responsible for this student team.
@@ -97,12 +98,12 @@ public class StudentTeam extends Team {
return sb.toString();
}
- public GHRepository getRepository() {
- return this.repository;
+ public String getRepositoryName() {
+ return this.repositoryName;
}
- public void setRepository(GHRepository repo) {
- this.repository = repo;
+ public void setRepositoryName(String repositoryName) {
+ this.repositoryName = repositoryName;
}
public TATeam getTaTeam() {
@@ -117,4 +118,17 @@ public class StudentTeam extends Team {
public String getDetailName() {
return this.generateRepoDescription();
}
+
+ @Override
+ public List> getDetailPairs() {
+ List> 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;
+ }
}
diff --git a/src/main/java/nl/andrewlalis/ui/control/listeners/management_view/PopupSelector.java b/src/main/java/nl/andrewlalis/ui/control/listeners/management_view/PopupSelector.java
new file mode 100644
index 0000000..28e5f18
--- /dev/null
+++ b/src/main/java/nl/andrewlalis/ui/control/listeners/management_view/PopupSelector.java
@@ -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) {
+
+ }
+}
diff --git a/src/main/java/nl/andrewlalis/ui/control/listeners/management_view/TableRowListener.java b/src/main/java/nl/andrewlalis/ui/control/listeners/management_view/TableRowListener.java
new file mode 100644
index 0000000..4904d5a
--- /dev/null
+++ b/src/main/java/nl/andrewlalis/ui/control/listeners/management_view/TableRowListener.java
@@ -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;
+ }
+
+}
diff --git a/src/main/java/nl/andrewlalis/ui/control/listeners/management_view/student_actions/RemoveFromCourseListener.java b/src/main/java/nl/andrewlalis/ui/control/listeners/management_view/student_actions/RemoveFromCourseListener.java
new file mode 100644
index 0000000..c0c9c3b
--- /dev/null
+++ b/src/main/java/nl/andrewlalis/ui/control/listeners/management_view/student_actions/RemoveFromCourseListener.java
@@ -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()));
+ }
+}
diff --git a/src/main/java/nl/andrewlalis/ui/control/listeners/management_view/student_actions/SetTeamListener.java b/src/main/java/nl/andrewlalis/ui/control/listeners/management_view/student_actions/SetTeamListener.java
new file mode 100644
index 0000000..0456f61
--- /dev/null
+++ b/src/main/java/nl/andrewlalis/ui/control/listeners/management_view/student_actions/SetTeamListener.java
@@ -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();
+ }
+}
diff --git a/src/main/java/nl/andrewlalis/ui/view/AbstractView.java b/src/main/java/nl/andrewlalis/ui/view/AbstractView.java
index 0d29dfe..7499af4 100644
--- a/src/main/java/nl/andrewlalis/ui/view/AbstractView.java
+++ b/src/main/java/nl/andrewlalis/ui/view/AbstractView.java
@@ -28,6 +28,11 @@ public abstract class AbstractView extends JFrame {
*/
private List 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
* values.
@@ -42,6 +47,7 @@ public abstract class AbstractView extends JFrame {
this.githubManager = githubManager;
this.childViews = new ArrayList<>();
this.parentViews = new ArrayList<>();
+ this.setIconImage(imageIcon.getImage());
this.setContentPane(this.buildContentPane());
this.setDefaultCloseOperation(defaultCloseOperation);
if (preferredSize != null) {
diff --git a/src/main/java/nl/andrewlalis/ui/view/ManagementView.java b/src/main/java/nl/andrewlalis/ui/view/ManagementView.java
index 669a65f..5e890f1 100644
--- a/src/main/java/nl/andrewlalis/ui/view/ManagementView.java
+++ b/src/main/java/nl/andrewlalis/ui/view/ManagementView.java
@@ -3,6 +3,8 @@ package nl.andrewlalis.ui.view;
import nl.andrewlalis.git_api.GithubManager;
import nl.andrewlalis.model.database.DbHelper;
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.table_models.StudentTableModel;
import nl.andrewlalis.ui.view.table_models.StudentTeamTableModel;
@@ -145,6 +147,13 @@ public class ManagementView extends AbstractView {
table.getSelectionModel().addListSelectionListener(listSelectionEvent -> {
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);
}
diff --git a/src/main/java/nl/andrewlalis/ui/view/dialogs/TeamChooserDialog.java b/src/main/java/nl/andrewlalis/ui/view/dialogs/TeamChooserDialog.java
new file mode 100644
index 0000000..3431df4
--- /dev/null
+++ b/src/main/java/nl/andrewlalis/ui/view/dialogs/TeamChooserDialog.java
@@ -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;
+ }
+
+}
diff --git a/src/main/java/nl/andrewlalis/ui/view/table_models/StudentTeamTableModel.java b/src/main/java/nl/andrewlalis/ui/view/table_models/StudentTeamTableModel.java
index c88ae14..a6300af 100644
--- a/src/main/java/nl/andrewlalis/ui/view/table_models/StudentTeamTableModel.java
+++ b/src/main/java/nl/andrewlalis/ui/view/table_models/StudentTeamTableModel.java
@@ -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
* 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.
@@ -90,7 +90,9 @@ public class StudentTeamTableModel extends AbstractTableModel {
case 0:
return team.getId();
case 1:
- return team.memberCount();
+ return (team.getRepositoryName() == null) ? "None" : team.getRepositoryName();
+ case 2:
+ return (team.getTaTeam() == null) ? "None" : team.getTaTeam().getDetailName();
default:
return this.getMemberInColumn(team, i1);
}
@@ -135,8 +137,9 @@ public class StudentTeamTableModel extends AbstractTableModel {
this.columns = new String[this.staticColumns.length + maxMembers];
this.columns[0] = this.staticColumns[0];
this.columns[1] = this.staticColumns[1];
+ this.columns[2] = this.staticColumns[2];
for (int i = 0; i < maxMembers; i++) {
- this.columns[i + 2] = "Member " + (i + 1);
+ this.columns[i + this.staticColumns.length] = "Member " + (i + 1);
}
}
}