undo
, redo
, history
and arrow key command navigation (including the code) were reused with some changes from AddressBook-Level4.Refer to the guide Setting up and getting started.
The Architecture Diagram given above explains the high-level design of the app.
Below is a quick overview of the main components and how they interact with each other.
Main components of the architecture
Main
(consisting of classes Main
and MainApp
) is in charge of the app launch and shutdown.
The bulk of the app's work is done by the following four components:
UI
: The UI of the app.Logic
: The command executor.Model
: Holds the data of the app in memory.Storage
: Reads data from and writes data to the hard disk.Commons
represent a collection of classes used by multiple other components.
How the architecture components interact with each other
The Sequence Diagram below shows how the components interact with each other for the scenario where the user issues the command delete s/A0249112A
.
Each of the four main components (also shown in the diagram above),
interface
with the same name as the component.{Component Name}Manager
class (which follows the corresponding API interface
mentioned in the previous point).For example, the Logic
component defines its API in the Logic.java
interface and implements its functionality using the LogicManager.java
class, which follows the Logic
interface. Other components interact with a given component through its interface rather than the concrete class (reason: to prevent outside components' being coupled to the implementation of a component), as illustrated in the (partial) class diagram below.
The sections below give more details of each component.
The API of this component is specified in Ui.java
The UI consists of a MainWindow
that is made up of parts e.g.CommandBox
, ResultDisplay
, StudentListPanel
, StatusBarFooter
, etc. All these, including the MainWindow
, inherit from the abstract UiPart
class, which captures the commonalities between classes that represent parts of the visible GUI.
The UI
component uses the JavaFx UI framework. The layout of these UI parts is defined in matching .fxml
files that are in the src/main/resources/view
folder. For example, the layout of the MainWindow
is specified in MainWindow.fxml
The UI
component,
Logic
component.Model
data so that the UI can be updated with the modified data.Logic
component because the UI
relies on the Logic
to execute commands.Model
component, as it displays the Student
object residing in the Model
.API : Logic.java
Here's a (partial) class diagram of the Logic
component:
How the Logic
component works:
Logic
is called upon to execute a command, it is passed to a ClassManagerParser
object, which in turn creates a parser that matches the command (e.g., DeleteCommandParser
) and uses it to parse the command.Command
object (more precisely, an object of one of its subclasses e.g., DeleteCommand
), which is executed by the LogicManager
.Model
when it is executed (e.g. to delete a student).CommandResult
object, which is returned from Logic
.Here are the other classes in Logic
(omitted from the class diagram above) that are used for parsing a user command:
How the parsing works:
ClassManagerParser
class creates an XYZCommandParser
(XYZ
is a placeholder for the specific command name, e.g. AddCommandParser
), which uses the other classes shown above to parse the user command and creates an XYZCommand
object (e.g., AddCommand
) which the ClassManagerParser
returns as a Command
object.XYZCommandParser
classes (e.g., AddCommandParser
, DeleteCommandParser
, etc.) inherit from the Parser
interface so that they can be treated similarly where possible, e.g during testing.API : Model.java
The Model
component,
Student
objects (which are contained in a UniqueStudentList
object).Student
objects (e.g., results of a search query) as a separate filtered list which is exposed to outsiders as an unmodifiable ObservableList<Student>
that can be 'observed' e.g. the UI can be bound to this list so that the UI automatically updates when the data in the list change.UserPref
object that represents the user’s preferences. This is exposed to the outside as a ReadOnlyUserPref
object.Model
represents data entities of the domain, they should make sense on their own without depending on other components)API : Storage.java
The Storage
component,
ClassManagerStorage
and UserPrefStorage
, which means it can be treated as either one (if only the functionality of only one is needed).Model
component (because the Storage
component's job is to save/retrieve objects that belong to the Model
)Classes used by multiple components are in the seedu.classmanager.commons
package.
This section describes some noteworthy details on how certain features are implemented.
This feature allows users to tag their student with labels to allow easier recognition of their students by their traits.
Tagging a student with Tag
is facilitated by TagCommand
, AddTagCommand
, DeleteTagCommand
and TagCommandParser
.
TagCommand
will replace all existing tags of a student with input tags.AddTagCommand
will add input tags to the existing tags of the student.DeleteTagCommand
will delete input tags from the existing tags of the student.TagCommandParser
will parse the user input and create the correct command object to execute.Note: Only 1 of the 3 commands will be executed per user input.
Here is a step-by-step example of how the tag command might be executed.
Step 1. User inputs the tag
command.
Step 2. Logic
will receive the input and pass it to a ClassManagerParser
object, which in turn creates a TagCommandParser
object to parse the command.
Step 3. Next TagCommandParser
will check for any action identifiers,
/add
or /delete
, which will create a AddTagCommand
object or DeleteTagCommand
object respectively,
else a TagCommand
object. ParseException
will be thrown for any invalid inputs.
Step 4a. AddTagCommand
will union the HashSet<Tag>
with the student's existing Tag
.
Step 4b. DeleteTagCommand
will remove all Tag
that are in the intersection of the student's existing Tag
and HashSet<Tag>
.
Step 4c. TagCommand
will replace all existing Tag
of the student with HashSet<Tag>
.
Step 5. TagCommand
updates the Student
with the new Tag
.
Step 6. TagCommand
updates the Model
with the updated Student by calling Model#setStudent()
.
Step 7. Finally, the TagCommand
creates a CommandResult with a success message and returns it to the LogicManager to complete the command execution. The GUI would also be updated with the change of status.
Note: For Step 5, 6 and 7, AddTagCommand
and DeleteTagCommand
behaves the same way as TagCommand
.
The following sequence diagram summarizes what happens when a user executes a tag
command:
The following activity diagram summarises what happens when a user executes a tag
command:
Aspect: TagCommand
Alternative 1 (current choice): Use different types of TagCommand to handle adding and deletion of tags.
Alternative 2: Replace all existing tags with input tags.
The undo/redo feature works similarly to the one implemented in AddressBook-Level 4, but with support for more commands and a limit to the number of Class Manager states stored. The undo/redo mechanism is facilitated by VersionedClassManager
. It extends ClassManager
with an undo/redo history, stored internally as a classManagerStateList
and currentStatePointer
. classManagerStateList
only stores up to 10 most recent states of Class Manager to avoid performance issues when a large number of commands are executed. Additionally, it implements the following operations:
VersionedClassManager#commit()
— Saves the current Class Manager state in its history.VersionedClassManager#undo()
— Restores the previous Class Manager state from its history.VersionedClassManager#redo()
— Restores a previously undone Class Manager state from its history.These operations are exposed in the Model
interface as Model#commitClassManager()
, Model#undoClassManager()
and Model#redoClassManager()
respectively.
Given below is an example usage scenario and how the undo/redo mechanism behaves at each step.
Step 1. The user launches the application for the first time. The VersionedClassManager
will be initialized with the initial Class Manager state and the currentStatePointer
pointing to that single Class Manager state.
Step 2. The user executes delete s/A0123456L
command to delete the student with the Student Number A0123456L in Class Manager. The delete
command calls Model#commitClassManager()
, causing the modified state of Class Manager after the delete s/A0123456L
command executes to be saved in the classManagerStateList
, and the currentStatePointer
is shifted to the newly inserted Class Manager state.
Step 3. The user executes add n/David …
to add a new student. The add
command also calls Model#commitClassManager()
, causing another modified Class Manager state to be saved into the classManagerStateList
.
Note: If a command fails its execution, it will not call Model#commitClassManager()
, so the Class Manager state will not be saved into the classManagerStateList
.
Step 4. The user now decides that adding the student was a mistake and decides to undo that action by executing the undo
command. The undo
command will call Model#undoClassManager()
, which will shift the currentStatePointer
once to the left, pointing it to the previous Class Manager state and restores Class Manager to that state.
Note: If the currentStatePointer
is at index 0, pointing to the initial ClassManager state, then there are no previous ClassManager states to restore. The undo
command uses Model#canundoClassManager()
to check if this is the case. If so, it will return an error to the user rather
than attempting to perform the undo.
The following sequence diagram shows how the undo operation works:
Note: The lifeline for UndoCommand
should end at the destroy marker (X), but due to a limitation of PlantUML, the lifeline reaches the end of the diagram.
The redo
command does the opposite — it calls Model#redoClassManager()
, which shifts the currentStatePointer
once to the right, pointing to the previously undone state, and restores Class Manager to that state.
Note: If the currentStatePointer
is at index classManagerStateList.size() - 1
, pointing to the latest Class Manager state, then there are no undone Class Manager states to restore. The redo
command uses Model#canRedoClassManager()
to check if this is the case. If so, it will return an error to the user rather than attempting to perform the redo.
Step 5. The user then decides to execute the command list
. Commands that do not modify Class Manager, such as list
, will usually not call Model#commitClassManager()
, Model#undoClassManager()
or Model#redoClassManager()
. Thus, the classManagerStateList
remains unchanged.
Step 6. The user executes clear
, which calls Model#commitClassManager()
. Since the currentStatePointer
is not pointing at the end of the classManagerStateList
, all Class Manager states after the currentStatePointer
will be purged. Reason: It no longer makes sense to redo the add n/David …
command. This is the behaviour that most modern desktop applications follow.
In order to implement undo
and redo
in Class Manager, load
and config
commands are not supported by undo
and redo
. This is because undoing load
and config
can cause Class Manager to be in an inconsistent state. To prevent this, load
and config
commands call Model#loadReset()
and Model#configReset()
, respectively. These methods essentially clear classManagerStateList
and reset the currentStatePointer
to the current Class Manager state, allowing 9 more states of Class Manager to be stored after load
and config
commands.
The following activity diagram summarizes what happens when a user executes a new command:
Aspect: How undo & redo executes:
Alternative 1 (current choice): Saves the entire Class Manager.
Alternative 2: Individual command knows how to undo/redo by itself.
delete
, just save the student being deleted).Aspect: Data structure to support the undo/redo commands
Alternative 1 (current choice): Use a list to store the history of Class Manager states.
HistoryManager
and VersionedClassManager
.Alternative 2: Use HistoryManager
for undo/redo.
HistoryManager
now needs to do two different things.Aspect: Commands that support undo & redo
load
and config
load
for missing saved files.config
command resets student Class Information.load
and config
.Aspect: Number of Class Manager states to store
The load feature allows users to load a saved JSON file into the app. Load allows data from the new JSON file to be displayed in Class Manager while setting the new default save file to be the new JSON file. The status bar footer also updates to show the current file path.
This feature is an improvement to the previous method of directly editing the classmanager.json
file located in [JAR file location]/data
. Users are now able to have multiple JSON files in [JAR file location]/data
and choose which file is to be loaded into Class Manager. This allows TAs with multiple courses to have a JSON file for each course and load the JSON file for the course they are currently teaching.
The load
command is facilitated by LoadCommand
and LoadCommandParser
. LoadCommand
attempts to read the JSON file and checks if the tutorial and assignment count for each student matches the current configuration of Class Manager. If the file is valid (each Student's information follows the format in the image below), it then calls setClassManager
and setClassManagerFilePath
of Model
to update the new save file path and Class Manager data to be displayed. LoadCommand
then resets VersionedClassManager
to clear the undo/redo history of Class Manager.
load
command.ClassManagerParser
processes the input and creates a new LoadCommandParser
.LoadCommandParser
then calls ArgumentTokenizer#tokenize(String argString, Prefix... prefixes) to extract the file name. If there are duplicate prefixes, a ParseException would be thrown.LoadCommandParser
then creates the LoadCommand
based on the processed input.Aspect: Files that can be loaded:
The config
command allows TAs to set the number of tutorials and the number of assignments in a module. This allows the Class Manager to be able to display the correct number of tutorials and assignments for the TA to enter the grades for each student. This also provides more flexibility to TAs as their class may differ from the default configuration of 13 tutorials and 6 assignments.
The config
command is facilitated by ConfigCommand
and ConfigCommandParser
. ConfigCommand
updates the tutorial and assignment count of Class Manager by calling setTutorialCount
and setAssignmentCount
of Model
to update the preferences.json
file. Simultaneously, it updates the static tutorial and assignment count of ClassDetails
to recreate the ClassDetails
objects for students accurately. All students in the current file will have their Class Information updated to reflect the new configuration. ConfigCommand
then resets the student shown in the view panel, as well as VersionedClassManager
, to clear the undo/redo history of Class Manager.
config
command.ClassManagerParser
processes the input and creates a new ConfigCommandParser
.ConfigCommandParser
then calls ArgumentTokenizer#tokenize(String argString, Prefix... prefixes) to extract the tutorial count and assignment count. If there are duplicate prefixes, a ParseException would be thrown.ConfigCommandParser
then creates the ConfigCommand
based on the processed input.In v1.2, config
was initially implemented as a command that users could only execute once before they started using Class Manager. This allows ClassDetails
to create fixed-length arrays for AssignmentTracker
, AttendanceTracker
and ClassParticipationTracker
.
However, this implementation was changed in v1.3 to allow users to execute config
multiple times. This allows users to reconfigure Class Manager if they have entered the wrong information previously. We decided to reset the Class Information of a student back to the default values of 0 for attendance, class participation and assignment grades, as it ensures a consistent implementation of config
regardless of whether the new tutorial count and assignment count were smaller or larger than the previous configuration.
In addition, the tutorial and assignment count was limited to an integer between 1 and 40 inclusive in v1.4. This prevents division by zero bugs encountered in data visualisation, as well as Class Manager being unresponsive when the user enters a large number of tutorials and assignments.
Aspect: Number of times Class Manager can be configured
The lookup
command allows TAs to search and filter for students in the Class Manager. This allows TAs to find the student they are looking for quickly, and perform subsequent operations such as editing Class Information for student(s). This also provides more flexibility to TAs as they may want to search for students based on different criteria.
Note: To shorten the sequence diagram, we use SCKP
as an abbreviation for StudentContainsKeywordsPredicate
.
The lookup
command is facilitated by LookupCommand
and LookupCommandParser
.
LookupCommandParser
will parse the user input and create a corresponding StudentContainsKeywordsPredicate
, which implements the Predicate<Student>
interface.
LookupCommand
will then call Model#updateFilteredStudentList()
to update the student list by utilizing the StudentContainsKeywordsPredicate
to test whether a student satisfies the given criteria or not. The filtered list will then be displayed in the UI.
lookup
command.ClassManagerParser
processes the input and creates a new LookupCommandParser
.LookupCommandParser
then calls ArgumentTokenizer#tokenize(String argString, Prefix... prefixes)
to extract the criteria provided by the user. If there are duplicate prefixes, a ParseException would be thrown.StudentContainsKeywordsPredicate
is then created based on the processed input.LookupCommandParser
then creates the LookupCommand
based on the processed input.Aspect: Criteria for lookup
Aspect: Criteria Validation
Alternative 1 (current choice): The LookupCommandParser
does not apply any validation to the user input.
LookupCommand
will still be executed. This can cause some confusion for the user.Alternative 2: The LookupCommandParser
will apply validation to the user input.
Aspect: Criteria Combination for complex lookup
Alternative 1 (current choice): Within a field, the operation is OR, and between fields the operation, is AND.
For example, lookup n/alex david c/T11 T12
will have the criteria:
(name contains alex OR david) AND (class number is T11 OR T12)
Alternative 2: The combination can be specified by the user.
For example, lookup n/alex \AND david \OR c/T11 \OR T12
will have the criteria:
(name contains alex AND david) OR (class number is T11 OR T12)
StudentContainsKeywordsPredicate
. In addition, the syntax can be confusing for the user. lookup n/alex \AND david \OR li
which can have two different interpretations:(name contains alex AND david) OR (name contains li)
(name contains alex) AND (name contains david OR li)
The theme
command allows TAs to toggle/switch between light and dark themes.
The theme
feature is facilitated by the ThemeCommand
, and inside the Model
component, the UserPrefs
class stores the current colour theme settings.
Here is a step-by-step example of how the theme command might be executed.
theme
command.Logic
component will receive the input and create a new ThemeCommand
object.ThemeCommand
is executed, it will call Model#toggleTheme()
to update the colour theme settings in the UserPrefs
class.MainWindow
class in the UI
component will then fetch the new colour theme settings from the UserPrefs
class.MainWindow
class will then update the GUI colour theme accordingly.Below is a sequence diagram that shows how the theme
command is executed.
Aspect: Fetching the new colour theme setting
Alternative 1 (current choice): The MainWindow
class fetches the new colour theme through the Logic
component.
UserPrefs
class.Alternative 2: The new setting is contained in the CommandResult
object.
MainWindow
class can use the new setting directly from the CommandResult
object.CommandResult
class will be modified to contain the new setting.The proposed class details mechanism for each student will be facilitated by ClassDetails
. It allows for the tracking
of a Student
's class details, such as their tutorial group, tutorial attendance, class participation, and assignment
grades. It will be stored as 3 separate classes to model each of the 3 different types of class details (We will
call them "Class Information"), and a tracker
class to act as the manager for each of the Class Information, with the trackers composing the ClassDetails
class.
The 3 different types of Class Information are:
Attendance
- Stores the details of a student's attendance in a specific tutorial. Attendance will be stored as
a boolean value.ClassParticipation
- Stores the details of a student's participation in a specific tutorial. Class participation
will be stored as a boolean value.Assignment
- Stores the details of a student's assignment grades for a specific tutorial. Assignment grades will be
stored as an integer value, with the total marks standardized to 100 marks.These components will be stored in their respective tracker classes, using Java Arrays to store the objects. The position of the classes in the array will correspond to the index of the tutorial or assignment. For example, the first index of the array will correspond to either the first tutorial or assignment, depending on the tracker class.
The tracker classes will be stored in the ClassDetails
class, which will be composed of the following classes:
AttendanceTracker
- Stores the Attendance
objects for a specific student.ClassParticipationTracker
- Stores the ClassParticipation
objects for a specific student.AssignmentTracker
- Stores the Assignment
objects for a specific student.These tracker classes will inherit from a tracker
interface. They will also support the following operations:
getPercentage()
- Returns the average grade of the student for the specific tracker class. For example, the average
tutorial attendance percentage or the average assignment score.getJson()
- Returns a Json Friendly representation of the tracker.Each of these tracker classes will be initialized with a specific size, which will be the number of tutorials or assignments.
Aspect: Class Information
classes
Alternative 1 (current choice): Use a class for each type of Class Information.
Alternative 2: Store class values as a primitive type (String or Integer).
Aspect: Tracker classes
Alternative 1 (current choice): Use a tracker class for each type of Class Information.
Alternative 2: Store class values as an Object Array.
The data visualisation feature allows users to visualize the Class Information
fields of each student. The display will be located inside the student list card, next to the other details of the students.
There will be 3 bar graphs associated with each student, one for each of the Class Information
fields, representing the overall percentage of each field across a semester.
The data visualisation feature is facilitated by each Class Information Tracker
. Each tracker will have a method that will calculate the average percentage of the field.
These methods are called by the StudentCard
class in the UI package within a method used to initialize the FXML bar chart.
The present feature allows users to mark a specific student to be present in a specific tutorial in the app.
This feature builds upon the current design of Student and ClassDetails.
Note: The diagram above only shows part of the interactions within the model component. The interactions within the logic component are similar to other commands.
The feature should be implemented based on the current design of Student and ClassDetails. Alternative designs may exist, such as treating the attendance and participation as association classes.
Note: Other similar features, such as absent
, class-part
, and grade
, are implemented similarly.
The view feature allows users to view the Class Information of their students.
Note: The view
command is the only way to change the student being viewed in the GUI
.
The view
command is facilitated by the ViewCommandParser
and the ViewCommand
. It uses Model#setSelectedStudent()
to select the student that is to be viewed in the GUI
.
Here is a step-by-step example of how a view
command is executed:
Step 1. User inputs a view
command.
Step 2. Logic
will receive the input and pass it to a ClassManagerParser
object, which in turn creates a ViewCommandParser
object to parse the command.
Step 3. ViewCommandParser
will check if the input is valid. If the input is valid, it will create a ViewCommand
object to execute the command. Else ParseException
is thrown.
Step 4. ViewCommand
will use Model#setSelectedStudent()
to set the requested student to be viewed in the GUI
.
The following sequence diagram will show what happens when a user executes a view
command:
The following activity diagram will show what happens when a user executes a view
command:
Aspect: ViewCommand
Alternative 1 (current choice): Using a command to view the Class Information of a student.
GUI
.Alternative 2: Listing all the Class Information of every student.
GUI
.Target user profile:
Value proposition:
Priorities: High (must have) - * * *
, Medium (nice to have) - * *
, Low (unlikely to have) - *
Priority | As a … | I want to … | So that I can… |
---|---|---|---|
* * * | TA | manually enter the details of students into my Class Manager | track the information |
* * * | TA | be able to delete students from the class | manage students who drop out |
* * * | TA | edit the contact information of students | maintain the correct information if it changes |
* * | TA | keep track of the attendance percentage of each student | use it for their participation grade |
* * | TA | be able to add the grades of each student in each tutorial | use it to view students that need help |
* | TA | be able to keep records of my students in past semesters | refer to the history of student performance |
* | TA | add comments to specific students | attach additional information to them |
* * * | TA | tag students with certain labels | filter and search more conveniently |
* * * | TA | lookup all students in a particular tutorial group | obtain their contact information |
* * | TA | search particular students across different tutorial groups | contact them easily |
* | TA | know the students I searched recently | minimize repeated searches |
* * | TA | filter students by tags/labels | categorise and organise students |
* * | TA | filter students by their year of study | gain a better understanding of the whole tutorial |
* | TA | have a composite filter for tutorial group attendance | look up the attendance of a particular tutorial group on a certain week |
* | TA | randomly select a specific number of students | use as a feature during teaching |
* * | TA | sort students by coding experience | group students with similar experience levels |
* * | TA | sort students based on their score marks | understand the performance of the whole class |
* * | TA | sort students by alphabetical order | compare to the attendance sheet |
* * | TA | sort students by their overall grades | identify students falling behind in my class |
* | TA | customise my GUI | use a theme that suits my desktop theme |
* | TA | enable dark mode for my device | use it at night |
* | TA | choose different layouts | select a comfortable layout |
* * | TA | have keyboard shortcuts for commonly used features | save time and fit my habit |
* * | TA | customise commands | save time and fit my habit |
* * * | TA | export and import app’s data | work on different devices |
* * * | TA | save queries and searches to the application | not lose progress |
* * * | new user | see usage instructions | refer to instructions when I forget how to use the app |
(For all use cases below, the System is Class Manager
, and the Actor is the user
, unless specified otherwise)
Use case: UC01 - Delete a student
MSS
User requests to delete a specific student with the student's student number
Class Manager deletes the student
Use case ends.
Extensions
1a. The given student number is invalid.
1a1. Class Manager shows an error message.
Use case resumes at step 1.
1b. The given student number does not exist in Class Manager.
1b1. Class Manager shows an error message.
Use case resumes at step 1.
Use case: UC02 - Tag a student with a label
MSS
User requests to list students
Class Manager shows a list of students
User requests to tag a specific student in the list
Class Manager tags the student
Use case ends.
Extensions
2a. The list is empty.
Use case resumes at step 1.
3a. The given student number is invalid.
3a1. Class Manager shows an error message.
Use case resumes at step 3.
3b. The given tag is invalid.
3b1. Class Manager shows an error message.
Use case resumes at step 3.
3c. The given student number does not belong to any student in the list.
3c1. Class Manager shows an error message.
Use case resumes at step 3.
Use case: UC03 - Loading a saved file
MSS
User copies saved JSON file to data folder
User requests to load JSON file
Class Manager reads and loads the JSON file
Class Manager updates the app to show the new data
Use case ends.
Extensions
3a. The JSON file cannot be found.
3a1. Class Manager shows an error message.
Use case resumes at step 2.
4a. The JSON file data is invalid.
4a1. Class Manager shows an error message.
Use case resumes at step 3.
Use case: UC04 - Look up a list of students
MSS
User requests to look up students with a given criteria.
Class Manager checks each student in the list with the given criteria.
Class Manager shows a list of students that match the criteria.
Use case ends.
Extensions
1a. There are no criteria given.
1a1. Class Manager shows an error message.
Use case ends.
2a. There are no students in the list that match the criteria.
2a1. Class Manager shows an error message.
Use case ends.
Use case: UC05 - Randomly select a specific number of students
MSS
User requests to randomly select a specific number of students.
Class Manager randomly selects the students from all students displayed.
Class Manager shows a list of students that are randomly selected.
Use case ends.
Extensions
1a. The number of students to be selected is more than the number of students in the list.
1a1. Class Manager shows an error message.
Use case resumes at step 1.
1b. The number of students to be selected is less than 1.
1b1. Class Manager shows an error message.
Use case resumes at step 1.
Use case: UC06 - Modifying a student's Class Information
MSS
User requests to modify a student's Class Information.
Class Manager modifies the student's Class Information.
Class Manager shows the student's updated Class Information.
Use case ends.
Extensions
1a. The student does not exist in Class Manager.
1a1. Class Manager shows an error message.
Use case resumes at step 1.
1b. The modifying request is invalid.
1b1. Class Manager shows an error message.
Use case resumes at step 1.
Use case: UC07 - Configuring module information
MSS
User requests to configure Class Manager.
Class Manager modifies the tutorial and assignment count.
Class Manager updates the app to show the new Class Information.
Use case ends.
Extensions
2a. The tutorial or assignment count is invalid.
2a1. Class Manager shows an error message.
Use case resumes at step 1.
Use case: UC08 - Undoing a command
MSS
User deletes a specified student (UC01).
User requests to undo the deletion.
Class Manager restores the deleted student.
Use case ends.
Use case: UC09 - Redoing a command
MSS
User undoes the deletion of a specified student (UC08).
User requests to redo the undone command.
Class Manager deletes the student.
Use case ends.
Use case: UC10 - Viewing command history
MSS
User requests to view command history.
Class Manager displays the command history of the current session.
Use case ends.
Use case: UC11 - Viewing a student's Class Information
MSS
Extensions
1a. The requested student does not exist in the Class Manager.
1a1. Class Manager displays an error message.
Use case resumes at step 1.
{More to be added}
11
or above installed.Given below are instructions to test the app manually.
Note: These instructions only provide a starting point for testers to work on; Testers are expected to do more exploratory testing.
Initial launch
Download the JAR file and copy it into an empty folder.
Launch the app by double-clicking the JAR file icon in your file explorer or running java -jar class-manager-2023.jar
in command terminal.
Expected: Shows the GUI with a set of sample contacts. The window size may not be optimal.
Save window preferences
Resize the window to an optimal size. Move the window to a different location. Close the window.
Re-launch the app by double-clicking the JAR file icon in your file explorer or running java -jar class-manager-2023.jar
in command terminal.
Expected: The most recent window size and window location are retained.
classmanager.json
and preferences.json
)Configure Class Manager with valid tutorial and assignment counts
config #t/3 #a/3
classmanager.json
.add n/John Doe p/999 e/john@gmail.com s/A0981234X c/T11
view s/A0981234X
present-all tut/1
config #t/4 #a/4
classmanager.json
, but their attendance bar graph is reset to 0.view s/A0981234X
Configure Class Manager with a tutorial count that is less than 1
config #t/0 #a/3
Invalid count values! The count value of tutorials cannot be less than 1.
Configure Class Manager with a valid tutorial count but is missing an assignment count
config #t/10
Invalid command format! config: Configures Class Manager with the module information. WARNING: Configuring Class Manager resets the grades, attendance and class participation details of all students. This cannot be undone. The default Class Manager is configured with 13 tutorials and 6 assignments. Parameters: #t/TUTORIAL_COUNT #a/ASSIGNMENT_COUNT Example: config #t/10 #a/4
Display help.
help
Add a new student to Class Manager.
add n/NAME s/STUDENT_NUMBER e/EMAIL
Add an already existing student to Class Manager.
Add a student without some required fields.
add n/NAME s/STUDENT_NUMBER e/EMAIL
, add n/NAME s/PHONE e/EMAIL
Add a comment to a student in Class Manager.
comment s/STUDENT_NUMBER cm/COMMENT
Add a comment to a student where the student is not in Class Manager (Invalid Student Number).
Add a comment to a student where the new comment is empty.
comment s/STUDENT_NUMBER cm/
Delete an existing student from Class Manager.
delete s/STUDENT_NUMBER
Delete a student with an invalid student number.
delete s/vnqvq1924
Edit an existing student's details in Class Manager.
edit STUDENT_NUMBER n/NAME
edit STUDENT_NUMBER s/NEW_STUDENT_NUMBER
Edit a student's details who do not exist in Class Manager.
List all students in Class Manager.
list
Lookup students in Class Manager using valid criteria.
lookup n/NAME
lookup c/CLASS_NUMBER
lookup t/TAG c/CLASS_NUMBER
Lookup students in Class Manager using invalid criteria.
lookup s/x
(where x is an invalid student number)No match found!
. This is because the lookup command does not do field validation.lookup c/class 11 n/john
(where "class 11" is an invalid class number)No match found!
. This is because the lookup command does not do field validation.
Lookup with no criteria given.
lookup
lookup c/
Tag an existing student in the Class Manager.
tag s/STUDENT_NUMBER t/TAG
Add a tags to student.
tag s/STUDENT_NUMBER /add t/TAG
Note: Even if the student has TAG tagged, the command ensures that the student will have TAG as one of the tags.
Delete tags from student.
tag s/STUDENT_NUMBER /delete t/TAG
Tag
TAG removed from existing tags.Note: Even if the student does not have TAG tagged, the command ensures that the student will not have TAG as one of the tags.
Delete all tags from student.
tag s/STUDENT_NUMBER t/
Attempt to tag a student not in Class Manager.
tag
command with a student number that is not in the Class Manager.Note: A similar way can be adopted to test absent
.
Mark an existing student as present in Class Manager.
present s/STUDENT_NUMBER tut/1
Note: A similar way can be adopted to test absent-all
.
Mark all displayed students as present in Class Manager.
present-all tut/1
Randomly select a specified number of students from the list of displayed students.
random 2
View a student who exists in Class Manager.
view s/STUDENT_NUMBER
View a student who does not exist not in Class Manager.
view
command with a student number that does not exist in Class ManagerInvalid Student number.
view s/x
(where x is an invalid student number)classmanager.json
and preferences.json
)classmanager.json
. Paste 2 copies of the file in the same directory as classmanager.json
. Rename the copies to t1.json
and t2.json
.classmanager.json
, as it will be used as the starting default file.load f/t1
t1.json
is loaded into the app. The status bar on the bottom left is updated to show the new file path.
The list of students shown in the GUI is the same as the one in classmanager.json
.
t2.json
with a text editor. Add some random text to the file or delete some text from the file.load f/t2
t2.json
is not loaded into the app. The status bar on the bottom left is unchanged.
File error details are shown in the Result Display Box.
load f/t3
Undo a command
Test case: clear
-> undo
Expected: The clear
command is undone. The list of students shown in the GUI is the same as the one before the clear
command.
Test case: add
-> undo
Expected: The add
command is undone. The newly added student is removed from the list of students.
Redo a command
Test case: clear
-> undo
-> redo
Expected: The clear
command is redone. The list of students shown in the GUI is empty.
Test case: add
-> add
-> undo
-> undo
-> redo
(Add 2 students, and then 2 undo with 1 redo)
Expected: The first add
command is redone. The first student is added back to the list of students.
history
list
list
.help
help
.history
help
as the most recent command at the top of the list, followed by list
below it.
classmanager.json
and preferences.json
)classmanager.json
. Paste 2 copies of the file in the same directory as classmanager.json
. Rename the copies to corrupt.json
and wrong.json
.preferences.json
to have the entry:"classManagerFilePath" : "data\\missing.json"
(Ensure that there is no file named missing.json
)
corrupt.json
, by adding or deleting lines of data and resulting in a file that does not match the valid JSON format. preferences.json
to have the entry:"classManagerFilePath" : "data\\corrupt.json"
preferences.json
to have the entries:"classManagerFilePath" : "data\\wrong.json",
"tutorialCount" : 1,
"assignmentCount" : 1,
(Ensure that the tutorialCount
and assignmentCount
are modified)
Toggle colour theme
theme
Exit the app.
exit
add
is currently case-sensitive. We will accept keywords such as Add
and ADD
in the future.R15
and SG06
.NONE
, MINIMAL
, SUFFICIENT
, ACTIVE
, VERY_ACTIVE
etc. to allow for better representation of student's efforts in class.\
or /
. We plan to allow users to add special characters to the name field in the future, so that names such as "Ravi s/o Veegan" will be allowed.TUTORIAL_INDEX
and TUTORIAL_SESSION
have the same meaning but with different names. We plan to switch every occurrence into TUTORIAL_INDEX
in the future, so that no confusion will be caused.