diff --git a/src/main/java/nl/andrewlalis/Main.java b/src/main/java/nl/andrewlalis/Main.java index e7702a7..faac15d 100644 --- a/src/main/java/nl/andrewlalis/Main.java +++ b/src/main/java/nl/andrewlalis/Main.java @@ -50,7 +50,7 @@ public class Main { "Program initialized."); GithubManager manager = new GithubManager(); - StartView startView = new StartView(manager); + StartView startView = new StartView(manager, "InitializerTesting", userOptions.get("token")); // SessionFactory factory = DbUtil.getSessionFactory(); // Session session = factory.openSession(); diff --git a/src/main/java/nl/andrewlalis/git_api/GithubManager.java b/src/main/java/nl/andrewlalis/git_api/GithubManager.java index 3ad9091..1f7c2a3 100644 --- a/src/main/java/nl/andrewlalis/git_api/GithubManager.java +++ b/src/main/java/nl/andrewlalis/git_api/GithubManager.java @@ -429,7 +429,7 @@ public class GithubManager { builder.issues(hasIssues); builder.description(description); builder.gitignoreTemplate("Java"); - builder.private_(isPrivate); + builder.private_(false); // TODO: Testing value of false. Production uses true. GHRepository repo = builder.create(); logger.fine("Created repository: " + repo.getName()); return repo; diff --git a/src/main/java/nl/andrewlalis/ui/control/listeners/create_assignments_view/NextListener.java b/src/main/java/nl/andrewlalis/ui/control/listeners/create_assignments_view/NextListener.java index 268cdc0..2970d7c 100644 --- a/src/main/java/nl/andrewlalis/ui/control/listeners/create_assignments_view/NextListener.java +++ b/src/main/java/nl/andrewlalis/ui/control/listeners/create_assignments_view/NextListener.java @@ -28,10 +28,19 @@ public class NextListener extends ViewChangeListener { protected boolean beforeChange() { CreateAssignmentsView assignmentsView = (CreateAssignmentsView) this.previousView; String repoName = assignmentsView.getRepositoryName(); + + // Check that the repository name is legitimate. + if (repoName.trim().length() == 0) { + JOptionPane.showMessageDialog(this.previousView, "Repository name is empty.", "Error", JOptionPane.WARNING_MESSAGE); + return false; + } + + // Check if the repository already exists. GithubManager manager = assignmentsView.getGithubManager(); if (manager.repoExists(repoName)) { return true; } else { + // If not, we have to create it here. int reply = JOptionPane.showConfirmDialog( assignmentsView, "The repository you gave does not exist.\nWould you like to create it?", @@ -39,7 +48,8 @@ public class NextListener extends ViewChangeListener { JOptionPane.YES_NO_OPTION); if (reply == JOptionPane.YES_OPTION) { try { - assignmentsView.getGithubManager().setupAssignmentsRepo(repoName, "", this.getTeachingAssistantsTeamName()); + String description = JOptionPane.showInputDialog(assignmentsView, "Enter a description for the repository.", "Assignments Repository Description", JOptionPane.QUESTION_MESSAGE); + assignmentsView.getGithubManager().setupAssignmentsRepo(repoName, description, this.getTeachingAssistantsTeamName()); return true; } catch (IOException e) { //e.printStackTrace(); @@ -52,6 +62,7 @@ public class NextListener extends ViewChangeListener { } } + // TODO: Replace this with a selector for an existing team of teaching assistants. Or configure this afterwards. private String getTeachingAssistantsTeamName() { String name = JOptionPane.showInputDialog(this.previousView, "Please enter (exactly) the name of Github team\nthat contains all teaching assistants.", "Select TA Team", JOptionPane.QUESTION_MESSAGE); return name; diff --git a/src/main/java/nl/andrewlalis/ui/control/listeners/input_students_file_view/FileSelectListener.java b/src/main/java/nl/andrewlalis/ui/control/listeners/input_students_file_view/FileSelectListener.java new file mode 100644 index 0000000..664fe44 --- /dev/null +++ b/src/main/java/nl/andrewlalis/ui/control/listeners/input_students_file_view/FileSelectListener.java @@ -0,0 +1,63 @@ +package nl.andrewlalis.ui.control.listeners.input_students_file_view; + +import nl.andrewlalis.model.StudentTeam; +import nl.andrewlalis.ui.view.InputStudentsFileView; +import nl.andrewlalis.util.TeamGenerator; + +import javax.swing.*; +import javax.swing.filechooser.FileFilter; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.io.File; +import java.io.IOException; +import java.util.List; + +/** + * Listens for when the user selects a CSV file to use to populate the teams list. + */ +public class FileSelectListener implements ActionListener { + + private InputStudentsFileView fileView; + + public FileSelectListener(InputStudentsFileView parent) { + this.fileView = parent; + } + + @Override + public void actionPerformed(ActionEvent actionEvent) { + // First check if the user has entered a valid team size. + if (this.fileView.getStudentsPerTeam() < 1) { + JOptionPane.showMessageDialog(this.fileView, "Invalid or missing team size.", "Error", JOptionPane.WARNING_MESSAGE); + return; + } + + // It is assumed that the team size is valid, so the user can choose a file. + JFileChooser chooser = new JFileChooser(); + chooser.setAcceptAllFileFilterUsed(false); + chooser.addChoosableFileFilter(new FileFilter() { + @Override + public boolean accept(File file) { + if (file.isDirectory()) { + return true; + } + return file.getName().toLowerCase().endsWith(".csv"); + } + + @Override + public String getDescription() { + return "CSV Files (*.csv)"; + } + }); + int fileResponse = chooser.showOpenDialog(this.fileView); + + if (fileResponse == JFileChooser.APPROVE_OPTION) { + int teamSize = this.fileView.getStudentsPerTeam(); + try { + List teams = TeamGenerator.generateFromCSV(chooser.getSelectedFile().getAbsolutePath(), teamSize); + System.out.println(teams); + } catch (IOException e) { + e.printStackTrace(); + } + } + } +} diff --git a/src/main/java/nl/andrewlalis/ui/view/AbstractView.java b/src/main/java/nl/andrewlalis/ui/view/AbstractView.java index 01e9cb7..5480cc1 100644 --- a/src/main/java/nl/andrewlalis/ui/view/AbstractView.java +++ b/src/main/java/nl/andrewlalis/ui/view/AbstractView.java @@ -4,6 +4,8 @@ import nl.andrewlalis.git_api.GithubManager; import javax.swing.*; import java.awt.*; +import java.util.ArrayList; +import java.util.List; /** * All views in the application will extend from this view, as a means of simplifying and organizing how visual @@ -16,6 +18,11 @@ public abstract class AbstractView extends JFrame { */ private GithubManager githubManager; + /** + * A list of views which are linked to this one via buttons in the component pane. + */ + private List childViews; + /** * Initializes the view by packing the content pane as it is defined by any child, and setting some generic swing * values. @@ -27,6 +34,7 @@ public abstract class AbstractView extends JFrame { AbstractView(String title, boolean startVisible, int defaultCloseOperation, Dimension preferredSize, GithubManager githubManager) { super(title); this.githubManager = githubManager; + this.childViews = new ArrayList<>(); this.setContentPane(this.buildContentPane()); this.setDefaultCloseOperation(defaultCloseOperation); if (preferredSize != null) { @@ -52,6 +60,16 @@ public abstract class AbstractView extends JFrame { // Child classes can define custom behavior here. } + /** + * Extends the default expose behaviour by recursively disposing all views which are linked to this one. + */ + public void dispose() { + for (AbstractView view : this.childViews) { + view.dispose(); + } + super.dispose(); + } + public GithubManager getGithubManager() { return githubManager; } @@ -69,4 +87,12 @@ public abstract class AbstractView extends JFrame { newPanel.setBorder(BorderFactory.createEmptyBorder(5, 2, 5, 2)); return newPanel; } + + /** + * Adds a view as linked to this one. That way, this view can be referenced elsewhere, even when hidden. + * @param view The view to link. + */ + protected final void addChildView(AbstractView view) { + this.childViews.add(view); + } } diff --git a/src/main/java/nl/andrewlalis/ui/view/CreateAssignmentsView.java b/src/main/java/nl/andrewlalis/ui/view/CreateAssignmentsView.java index 7fb9473..22d5418 100644 --- a/src/main/java/nl/andrewlalis/ui/view/CreateAssignmentsView.java +++ b/src/main/java/nl/andrewlalis/ui/view/CreateAssignmentsView.java @@ -31,13 +31,20 @@ public class CreateAssignmentsView extends AbstractView { @Override protected JPanel buildContentPane() { JPanel contentPane = new JPanel(); - contentPane.setLayout(new BorderLayout()); + + JPanel fieldPanel = new JPanel(); + fieldPanel.setLayout(new BoxLayout(fieldPanel, BoxLayout.PAGE_AXIS)); + this.repositoryNameField = new JTextField(); - contentPane.add(this.generateTextFieldPanel("Repository name:", this.repositoryNameField), BorderLayout.CENTER); + fieldPanel.add(this.generateTextFieldPanel("Assignments repository name:", this.repositoryNameField)); + contentPane.add(fieldPanel, BorderLayout.CENTER); + JButton nextButton = new JButton("Next"); - nextButton.addActionListener(new NextListener(this, new InputStudentsFileView(this.getGithubManager()))); + InputStudentsFileView inputStudentsFileView = new InputStudentsFileView(this.getGithubManager()); + this.addChildView(inputStudentsFileView); + nextButton.addActionListener(new NextListener(this, inputStudentsFileView)); contentPane.add(nextButton, BorderLayout.SOUTH); return contentPane; diff --git a/src/main/java/nl/andrewlalis/ui/view/InputStudentsFileView.java b/src/main/java/nl/andrewlalis/ui/view/InputStudentsFileView.java index 6c48e80..10a77b6 100644 --- a/src/main/java/nl/andrewlalis/ui/view/InputStudentsFileView.java +++ b/src/main/java/nl/andrewlalis/ui/view/InputStudentsFileView.java @@ -1,6 +1,7 @@ package nl.andrewlalis.ui.view; import nl.andrewlalis.git_api.GithubManager; +import nl.andrewlalis.ui.control.listeners.input_students_file_view.FileSelectListener; import javax.swing.*; import java.awt.*; @@ -10,6 +11,8 @@ import java.awt.*; */ public class InputStudentsFileView extends AbstractView { + private JTextField studentsPerTeamField; + InputStudentsFileView(GithubManager manager) { super("Input Students CSV", false, @@ -18,12 +21,27 @@ public class InputStudentsFileView extends AbstractView { manager); } + public int getStudentsPerTeam() { + return Integer.parseUnsignedInt(this.studentsPerTeamField.getText()); + } + @Override protected JPanel buildContentPane() { JPanel contentPane = new JPanel(new BorderLayout()); + JLabel helpLabel = new JLabel("Please select the CSV file containing student sign-up responses."); + contentPane.add(helpLabel, BorderLayout.NORTH); + + JPanel inputPanel = new JPanel(); + inputPanel.setLayout(new BoxLayout(inputPanel, BoxLayout.PAGE_AXIS)); + JButton selectFileButton = new JButton("Select File"); - contentPane.add(selectFileButton, BorderLayout.CENTER); + this.studentsPerTeamField = new JTextField("2"); + inputPanel.add(this.generateTextFieldPanel("How many students per team?", this.studentsPerTeamField)); + selectFileButton.addActionListener(new FileSelectListener(this)); + inputPanel.add(selectFileButton); + + contentPane.add(inputPanel, BorderLayout.CENTER); JButton doneButton = new JButton("Done"); contentPane.add(doneButton, BorderLayout.SOUTH); diff --git a/src/main/java/nl/andrewlalis/ui/view/StartView.java b/src/main/java/nl/andrewlalis/ui/view/StartView.java index 65fde1a..c53ebc8 100644 --- a/src/main/java/nl/andrewlalis/ui/view/StartView.java +++ b/src/main/java/nl/andrewlalis/ui/view/StartView.java @@ -29,6 +29,18 @@ public class StartView extends AbstractView { githubManager); } + /** + * Constructs the starting view, with pre-defined organization and access tokens. + * @param githubManager A reference to the github manager this application uses. + * @param organizationName The name of the organization. + * @param accessToken The access token from the user. + */ + public StartView(GithubManager githubManager, String organizationName, String accessToken) { + this(githubManager); + this.organizationNameField.setText(organizationName); + this.accessTokenField.setText(accessToken); + } + public String getOrganizationName() { return this.organizationNameField.getText(); } @@ -44,13 +56,15 @@ public class StartView extends AbstractView { JPanel infoInputPanel = new JPanel(); infoInputPanel.setLayout(new BoxLayout(infoInputPanel, BoxLayout.PAGE_AXIS)); this.organizationNameField = new JTextField(); - infoInputPanel.add(this.generateTextFieldPanel("Organization name:", this.organizationNameField)); this.accessTokenField = new JTextField(); + infoInputPanel.add(this.generateTextFieldPanel("Organization name:", this.organizationNameField)); infoInputPanel.add(this.generateTextFieldPanel("Access token:", this.accessTokenField)); JPanel buttonsPanel = new JPanel(); JButton assignmentsViewButton = new JButton("Start New Course"); - assignmentsViewButton.addActionListener(new CreateAssignmentsRepoListener(this, new CreateAssignmentsView(this.getGithubManager()))); + CreateAssignmentsView assignmentsView = new CreateAssignmentsView(this.getGithubManager()); + this.addChildView(assignmentsView); + assignmentsViewButton.addActionListener(new CreateAssignmentsRepoListener(this, assignmentsView)); JButton managementViewButton = new JButton("Manage Existing Course"); buttonsPanel.add(assignmentsViewButton);