diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index 44b5cfc7fd7..3c62f58c9b9 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -264,99 +264,6 @@ Step 1. The user launches the application, which is populated with a list of the Step 2. The user executes `grade 87654321 m/CS2103T g/A` command to assign an A `Grade` to Bernice's CS2103T `Module`. Bernice now has a CS2103T `Module` graded A in their list of modules. -### \[Proposed\] Undo/redo feature - -#### Proposed Implementation - -The proposed undo/redo mechanism is facilitated by `VersionedAddressBook`. It extends `AddressBook` with an undo/redo history, stored internally as an `addressBookStateList` and `currentStatePointer`. Additionally, it implements the following operations: - -* `VersionedAddressBook#commit()` — Saves the current address book state in its history. -* `VersionedAddressBook#undo()` — Restores the previous address book state from its history. -* `VersionedAddressBook#redo()` — Restores a previously undone address book state from its history. - -These operations are exposed in the `Model` interface as `Model#commitAddressBook()`, `Model#undoAddressBook()` and `Model#redoAddressBook()` 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 `VersionedAddressBook` will be initialized with the initial address book state, and the `currentStatePointer` pointing to that single address book state. - - - -Step 2. The user executes `delete 12345678` command to delete the person with Student ID of `12345678` in the address book. The `delete` command calls `Model#commitAddressBook()`, causing the modified state of the address book after the `delete 12345678` command executes to be saved in the `addressBookStateList`, and the `currentStatePointer` is shifted to the newly inserted address book state. - - - -Step 3. The user executes `add id/12345678 …​` to add a new person. The `add` command also calls `Model#commitAddressBook()`, causing another modified address book state to be saved into the `addressBookStateList`. - - - - - -**Note:** If a command fails its execution, it will not call `Model#commitAddressBook()`, so the address book state will not be saved into the `addressBookStateList`. - - - -Step 4. The user now decides that adding the person was a mistake, and decides to undo that action by executing the `undo` command. The `undo` command will call `Model#undoAddressBook()`, which will shift the `currentStatePointer` once to the left, pointing it to the previous address book state, and restores the address book to that state. - - - - - - -**Note:** If the `currentStatePointer` is at index 0, pointing to the initial AddressBook state, then there are no previous AddressBook states to restore. The `undo` command uses `Model#canUndoAddressBook()` 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 an undo operation goes through the `Logic` component: - - - - - -**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 diagram. - - - -Similarly, how an undo operation goes through the `Model` component is shown below: - - - -The `redo` command does the opposite — it calls `Model#redoAddressBook()`, which shifts the `currentStatePointer` once to the right, pointing to the previously undone state, and restores the address book to that state. - - - -**Note:** If the `currentStatePointer` is at index `addressBookStateList.size() - 1`, pointing to the latest address book state, then there are no undone AddressBook states to restore. The `redo` command uses `Model#canRedoAddressBook()` 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 the address book, such as `list`, will usually not call `Model#commitAddressBook()`, `Model#undoAddressBook()` or `Model#redoAddressBook()`. Thus, the `addressBookStateList` remains unchanged. - - - -
- -Step 6. The user executes `clear`, which calls `Model#commitAddressBook()`. Since the `currentStatePointer` is not pointing at the end of the `addressBookStateList`, all address book states after the `currentStatePointer` will be purged. Reason: It no longer makes sense to redo the `add n/David …​` command. This is the behavior that most modern desktop applications follow. - - - -The following activity diagram summarizes what happens when a user executes a new command: - - - -#### Design considerations: - -**Aspect: How undo & redo executes:** - -* **Alternative 1 (current choice):** Saves the entire address book. - * Pros: Easy to implement. - * Cons: May have performance issues in terms of memory usage. - -* **Alternative 2:** Individual command knows how to undo/redo by - itself. - * Pros: Will use less memory (e.g. for `delete`, just save the person being deleted). - * Cons: We must ensure that the implementation of each individual command are correct. - -------------------------------------------------------------------------------------------------------------------- @@ -378,12 +285,13 @@ The following activity diagram summarizes what happens when a user executes a ne **Target user profile**: -* Tertiary Teacher/Educator -* has a need to manage a significant number of contacts -* requires a tool to keep communication organised across large groups -* requires support for efficient tracking of academic progress +* Teachers in tertiary institutions. +* Has a need to manage a significant number of contacts. +* Requires a tool to keep communication organised across large groups. +* Requires dedicated support for tracking of academic progress. +* Prefers typing and is familiar with command-line interfaces. -**Value proposition**: save important time through simplification of student-parent contact management, enhancement in communication tracking and integrated progress reports +**Value proposition**: Provides teachers comfortable with CLI-based interfaces an efficient platform for contact management and student academic progress tracking.
@@ -391,29 +299,27 @@ The following activity diagram summarizes what happens when a user executes a ne Priorities: High (must have) - `* * *`, Medium (nice to have) - `* *`, Low (unlikely to have) - `*` -| Priority | As a …​ | I want to …​ | So that I can…​ | -|----------|--------------------|------------------------------------------------|-----------------------------------------------------------------------------| -| `* * *` | new teacher | add a contact | keep track of them | -| `* * *` | teacher | delete a contact | remove contacts that I no longer need | -| `* * *` | teacher | add a grade to a contact | keep track of a student's grades | -| `* * *` | teacher | add a student's details | keep track of the students under me | -| `* *` | teacher | edit a contact | update contact information without having to delete it | -| `* *` | teacher | search for a contact | find the contact I am looking for without having to scroll through the list | -| `* *` | frequent teacher | add tags or labels to contacts | group the many contacts that are in the application by a commonality | -| `* *` | frequent teacher | filter contacts by labels or tags | filter out irrelevant contacts | -| `* *` | frequent teacher | mass add contacts | add multiple contacts without having to do so one by one | -| `* *` | frequent teacher | mass delete contacts | delete multiple contacts without having to do so one by one | -| `* *` | teacher | add next of kins' contacts | contact the relevant individual in case of emergencies | -| `*` | frequent teacher | do custom sorts for contacts | shift relevant contacts near the top of the list of contacts | -| `*` | new teacher | see guided tours and tooltips | familiarise myself with the application interface | -| `*` | long-time teacher | archive contacts | reduce clutter in the application without permanently deleting the contact | -| `*` | long-time teacher | refactor tags or labels | mass edit tags or labels if necessary | -| `*` | new teacher | see the application populated with sample data | see what the application interface looks like | -| `*` | frequent teacher | add descriptions to contacts | be reminded of various traits a particular individual might have | -| `*` | frequent teacher | undo previous action | undo a mistake without having to delete or edit any contacts | -| `*` | long-time teacher | export contact data | have a backup data file in case anything happens to the application | -| `*` | long-time teacher | import contact data | load data from a file to restore lost or missing data | -| `*` | long-time teacher | access communication history | be well-prepared for upcoming meetings | +| Priority | As a …​ | I want to …​ | So that I can…​ | +|----------|----------------------------|---------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------| +| `* * *` | teacher | add a contact | have easy access to contacts | +| `* * *` | teacher | delete a contact | remove contacts that I no longer need | +| `* * *` | teacher | add contact details like email, address, phone number, modules etc. | keep track of my contacts' details | +| `* * *` | teacher | assign a grade to a module that my student is taking | keep track of a student's grades and academic progress | +| `* * *` | teacher | view contact information | have a clear visual reference for contact information | +| `* *` | teacher | edit a contact | update contact information without having to delete it | +| `* *` | teacher | search for a contact | find the contact I am looking for without having to scroll through the list | +| `* *` | teacher | add roles/tags to contacts | group the many contacts that are in the application by their type (e.g. student, tutor etc.) | +| `* *` | teacher | filter contacts by labels or tags | have an easy visual reference with irrelevant contacts filtered out | +| `* *` | new user | access a page that teaches me how to use the application | familiarise myself with the application interface | +| `* *` | efficient CLI user | navigate command history (like in other CLI-based applications) | easily load previously entered commands without having to re-type commands from scratch (to save time) | +| `*` | new user | see the application populated with sample data | see what the application interface looks like | +| `*` | mistake-prone user | undo previous action | undo a mistake without having to delete or edit any contacts | +| `*` | teacher with many contacts | perform mass operations on contacts | perform operations (add, edit, delete etc.) on multiple contacts without having to do so one by one | +| `*` | organised teacher | archive contacts | reduce clutter in the application without permanently deleting the contact | +| `*` | careful teacher | export contact data | have a backup data file in case anything happens to the application | +| `*` | careful teacher | import contact data | load data from a file to restore lost or missing data | + +
@@ -421,26 +327,30 @@ Priorities: High (must have) - `* * *`, Medium (nice to have) - `* *`, Low (unli (For all use cases below, the **System** is the `EduContacts` and the **Actor** is the `user`, unless specified otherwise) -**Use case: UC01 - Add a student** +--- + +#### UC01 - Add a contact **MSS** -1. User adds a student to the list of contacts. +1. User adds a contact to the list of contacts. 2. EduContacts updates the list of contacts. Use case ends. **Extensions** -* 1a. EduContacts detects an error in the given data. +* 1a. EduContacts detects an error in the user input. - * 1a1. EduContacts shows an error message. + * 1a1. EduContacts provides an appropriate error message as feedback to user. Use case ends. -**Use case: UC02 - Search for a student** +--- + +#### UC02 - Search for a student -**Preconditions: The list of contacts is not empty** +**Preconditions:** The list of contacts is not empty. **MSS** @@ -451,156 +361,116 @@ Priorities: High (must have) - `* * *`, Medium (nice to have) - `* *`, Low (unli **Extensions** -* 1a. EduContacts detects an error in the given data. +* 1a. EduContacts detects an error in the user input (command format, student does not exist etc.). - * 1a1. EduContacts shows an error message. + * 1a1. EduContacts provides an appropriate error message as feedback to user. Use case ends. -* 2a. EduContacts is unable to locate the student. - - Use case ends. +--- -**Use case: UC03 - Add a grade for a student** +#### UC03 - Add a module to a student** **MSS** -1. User searches for the student (UC02) they wish to add a grade for. -2. User adds a grade for the student. + +1. User searches for the student (UC02) they wish to add a module for. +2. User adds a module to the student in the list. 3. EduContacts updates the list of contacts. Use case ends. **Extensions** -* 1a. User is unable to locate the student. +* 1a. EduContacts detects an error in the user input (command format, student does not exist, duplicate module etc.). - Use case ends. + * 1a1. EduContacts provides an appropriate error message as feedback to user. -* 2a. EduContacts detects an error in the given data. + Use case ends. - * 2a1. EduContacts shows an error message. +--- - Use case ends. +#### UC04 - Add a grade for a student -**Use case: UC04 - Delete a student** +**Preconditions:** The student has a module already added (UC03). **MSS** - -1. User searches for the student (UC02) they wish to delete from the list. -2. User deletes the student in the list. +1. User searches for the student (UC02) they wish to add a grade for. +2. User adds a grade for the student. 3. EduContacts updates the list of contacts. Use case ends. **Extensions** -* 1a. User is unable to locate the student. - - Use case ends. +* 1a. EduContacts detects an error in the user input (command format, student or module does not exist etc.). -* 2a. EduContacts detects an error in the given data. - - * 2a1. EduContacts shows an error message. + * 1a1. EduContacts provides an appropriate error message as feedback to user. Use case ends. -**Use case: UC05 - Edit a student's details** -**MSS** +* 2a. The module is already graded. -1. User searches for the student (UC02) they wish to edit. -2. User edits the details of the student in the list. -3. EduContacts updates the list of contacts. - - Use case ends. - -**Extensions** - -* 1a. User is unable to locate the student. - - Use case ends. - -* 2a. EduContacts detects an error in the given data. - - * 2a1. EduContacts shows an error message. + * 2a1. EduContacts overwrites the old grade with the new grade. Use case ends. -**Use case: UC06 - Add a module to a student** +--- + +#### Use case: UC05 - Delete a student **MSS** -1. User searches for the student (UC02) they wish to add a module for. -2. User adds a module to the student in the list. +1. User searches for the student (UC02) they wish to delete from the list. +2. User deletes the student in the list. 3. EduContacts updates the list of contacts. Use case ends. **Extensions** -* 1a. User is unable to locate the student. - - Use case ends. +* 1a. EduContacts detects an error in the user input (command format, student does not exist etc.). -* 2a. EduContacts detects an error in the given data. - - * 2a1. EduContacts shows an error message. + * 1a1. EduContacts provides an appropriate error message as feedback to user. Use case ends. -* 2b. Student already has the module. - - * 2b1. EduContacts shows an error message. - - Use case ends. +--- -**Use case: UC07 - Grade a student** +#### Use case: UC06 - Edit a student's details **MSS** -1. User searches for the student (UC02) they wish to grade. -2. User grades a module the student is taking. +1. User searches for the student (UC02) they wish to edit. +2. User edits the details of the student in the list. 3. EduContacts updates the list of contacts. Use case ends. **Extensions** -* 1a. User is unable to locate the student. - - Use case ends. - -* 2a. EduContacts detects an error in the given data. +* 1a. EduContacts detects an error in the user input (command format, student does not exist etc.). - * 2a1. EduContacts shows an error message. + * 1a1. EduContacts provides an appropriate error message as feedback to user. Use case ends. -* 2b. The module is already graded. - - * 2b1. EduContacts overwrites the old grade with the new grade. - - Use case ends. +--- -**Use case: UC08 - Add contacts of next-of-kins of a student** +#### UC07 - Filter contacts based on properties **MSS** -1. User searches for the student (UC02) they wish to add contacts of next-of-kins for. -2. User adds contacts of next-of-kins of the student in the list. -3. EduContacts updates the list of contacts. +1. User provides a set of contact-related conditions. +2. EduContacts updates the list view to show contacts matching the provided conditions. Use case ends. **Extensions** -* 1a. User is unable to locate the student. - - Use case ends. - -* 2a. EduContacts detects an error in the given data. +* 1a. EduContacts detects an error in the user input (command format etc.). - * 2a1. EduContacts shows an error message. + * 1a1. EduContacts provides an appropriate error message as feedback to user. Use case ends. @@ -684,71 +554,196 @@ testers are expected to do more *exploratory* testing. ### Launch and shutdown -1. Initial launch +#### Initial launch + +1. Ensure you have Java `17` or above installed in your computer. + [Download Java here](https://www.oracle.com/sg/java/technologies/downloads/) if you haven't already. + + Note that Mac users should use the specific Azul JDK 17 distribution specified in [this guide](https://se-education.org/guides/tutorials/javaInstallationMac.html). + +2. Download the latest `.jar` file from [here](https://github.com/AY2425S1-CS2103T-F15-2/tp/releases). + +3. Copy the file to the folder you want to use as the home folder for your EduContacts. + +4. To run EduContacts, open a command terminal. + + To navigate to the folder where you placed the `.jar` file, use the `cd` command. For example, if you placed the file in a folder named `EduContacts` on your desktop, you would enter: + + ```bash + cd ~/Desktop/EduContacts + ``` + + and use the following command to run the application: + + ```bash + java -jar educontacts.jar + ``` + + A GUI similar to the screenshot below should appear in a few seconds. Note how the app contains some sample data.
- 1. Download the jar file and copy into an empty folder. + ![Ui](images/Ui.png) - 2. Double-click the jar file.
- Expected: Shows the GUI with a set of sample contacts. The window size may not be optimum. +--- -2. Saving window preferences +#### Saving window preferences - 1. Resize the window to an optimum size. Move the window to a different location. Close the window. +1. Resize the window to an optimum size. Move the window to a different location. Close the window. - 2. Re-launch the app by double-clicking the jar file.
- Expected: The most recent window size and location is retained. +2. Re-launch the app by double-clicking the jar file.
+ Expected: The most recent window size and location is retained.
-### Deleting a person +### Commands Testing + +#### Help Command + +**Opening the help window** +* **Test case:** `help` +* **Expected:** The help window opens, displaying a comprehensive list of available commands and their usage. + +**Using the help button** +* **Test case:** Click the "Help" button in the application GUI. +* **Expected:** The help window opens, displaying a comprehensive list of available commands and their usage. + +#### Add Command + +**Adding a valid person** +* **Test case:** `add 12345678 n/John Doe p/91234567 e/johndoe@example.com a/123 Example Street c/Computer Science r/Student` +* **Expected:** A new contact is added with the specified details. The list now includes the new contact, and a success message is shown. + +**Adding a duplicate person** +* **Prerequisites:** The person to add already exists in the list with the same Student ID `12345678`. +* **Test case:** `add 12345678 n/John Doe p/91234567 e/johndoe@example.com a/123 Example Street c/Computer Science r/Student` +* **Expected:** The addition fails, and an error message about the duplicate Student ID is shown. + +--- + +#### Edit Command + +**Editing an existing person** +* **Prerequisites:** List contains a person with Student ID `12345678`. +* **Test case:** `edit 12345678 p/98765432` +* **Expected:** The contact's phone number is updated to `98765432`. The updated details are shown in the success message. + +**Editing a non-existing person** +* **Prerequisites:** List does not contain a person with Student ID `00000000` +* **Test case:** `edit 00000000 p/98765432` +* **Expected:** The edit fails, and an error message about the non-existent Student ID is shown. + +**Editing with invalid input** +* **Test case:** `edit 12345678 p/invalidPhoneNumber` +* **Expected:** The edit fails, and an error message about the invalid phone number format is shown. + +--- + +#### Filter Command + +**Filter by name** +* **Test case:** `filter n/John` +* **Expected:** The list shows all persons with "John" in their name. A success message is shown. + +**Filter by course** +* **Test case:** `filter c/Computer Science` +* **Expected:** The list shows all persons enrolled in "Computer Science." A success message is shown. + +**Filter by multiple attributes** +* **Test case:** `filter n/John c/Computer Science` +* **Expected:** An error message about invalid multiple filter conditions is shown. -1. Deleting a person while all persons are being shown +--- + +#### Module Command + +**Adding a module to an existing person** +* **Prerequisites:** List contains a person with Student ID `12345678`. +* **Test case:** `module 12345678 m/CS2103T` +* **Expected:** The module "CS2103T" is added to the person's module list. A success message is shown. + +**Adding a duplicate module** +* **Prerequisites:** The person already has "CS2103T" as a module. +* **Test case:** `module 12345678 m/CS2103T` +* **Expected:** The addition fails, and an error message about the duplicate module is shown. + +--- - 1. Prerequisites: List all persons using the `list` command. Multiple persons in the list. One person in the list has Student ID `12345678`. +#### Grade Command - 2. Test case: `delete 12345678`
- Expected: Person with Student ID `12345678` is deleted. Details of the deleted contact shown in the status message. Timestamp in the status bar is updated. +**Adding a grade to a module** +* **Prerequisites:** The person with Student ID `12345678` has "CS2103T" in their module list. +* **Test case:** `grade 12345678 m/CS2103T g/A` +* **Expected:** The grade "A" is assigned to "CS2103T." A success message is shown. - 3. Test case: `delete 1234 5678`
- Expected: No person is deleted. Error details shown in the status message. Status bar remains the same. +**Adding a grade to a non-existent module** +* **Test case:** `grade 12345678 m/CS9999 g/B` +* **Expected:** The addition fails, and an error message about the non-existent module is shown. - 4. Other incorrect delete commands to try: `delete`, `delete x`, `...` (where x is a Student ID that no student in the list has)
- Expected: Similar to previous. +**Adding an invalid grade** +* **Test case:** `grade 12345678 m/CS2103T g/Z` +* **Expected:** The addition fails, and an error message about the invalid grade is shown. -2. Deleting a person while only one person is being shown +--- - 1. Prerequisites: Filter persons using the `filter` command until only one person remains. Multiple persons in the list. Person that remains has Student ID `12345678`. One person in the list has Student ID `11111111` +#### Find Command - 2. Test case: `delete 12345678`
- Expected: Person with Student ID `12345678` is deleted. Details of the deleted contact shown in the status message. Timestamp in the status bar is updated. List of persons shown is now blank. +**Finding an existing person** +* **Test case:** `find 12345678` +* **Expected:** The contact details of the person with Student ID `12345678` are shown in the result panel. - 3. Test case: `delete 11111111`
- Expected: No person is deleted. Error details shown in the status message. Status bar remains the same. +**Finding a non-existing person** +* **Test case:** `find 00000000` +* **Expected:** An error message about the non-existent Student ID is shown. -3. Deleting a person while no persons are in the list +--- - 1. Prerequisites: Delete all persons in the list using the `clear` command. +#### Clear Command + +**Clearing all entries** +* **Test case:** `clear` +* **Expected:** All persons are removed from the list. A success message is shown. + +--- + +#### Exit Command + +**Exiting the application** +* **Test case:** `exit` +* **Expected:** The application closes successfully without errors. + +--- + +#### Navigating Command History +**Navigating to previous commands** +* **Test case:** Execute several successful commands (e.g., `list`, `add 12345678 n/John Doe p/91234567 e/johndoe@example.com a/123 Example Street c/Computer Science r/Student`, `filter n/John`). +Then, press the UP arrow key in the Command Box. +* **Expected:** Each press of the UP arrow key navigates backward through the previously executed commands, displaying them in the Command Box. + +**Navigating to next commands** +* **Prerequisites:** Use the UP arrow key to navigate to a previous command in the Command Box. +* **Test case:** Press the DOWN arrow key. +* **Expected:** Each press of the DOWN arrow key navigates forward through the command history until the most recent command is displayed. +If no newer commands exist, the Command Box becomes empty. - 2. Test case: `delete 12345678`
- Expected: No person is deleted. Error details shown in the status message. Status bar remains the same.
### Saving data -1. Dealing with missing data files +#### Dealing with missing data files - 1. To simulate a missing file, in the same folder as the jar file, navigate to the `data` folder and delete the `address.json` file in the folder. +1. To simulate a missing file, in the same folder as the jar file, navigate to the `data` folder and delete the `address.json` file in the folder. - 2. Launch EduContacts by double-clicking the jar file.
- Expected: EduContacts is populated by a set of default list of persons. A new `address.json` file will be created in the `data` folder after closing the app or executing a command. +2. Launch EduContacts by double-clicking the jar file.
+ Expected: EduContacts is populated by a set of default list of persons. A new `address.json` file will be created in the `data` folder after closing the app or executing a command. + +--- -2. Dealing with corrupted data files +#### Dealing with corrupted data files - 1. To simulate a corrupted file, navigate to the `data` folder and remove a curly brace at the end of the file. +1. To simulate a corrupted file, navigate to the `data` folder and remove a curly brace at the end of the file. - 2. Launch EduContacts by double-clicking the jar file.
- Expected: EduContacts has a blank list of persons. A new `address.json` file will be created in the `data` folder after closing the app or executing a command. +2. Launch EduContacts by double-clicking the jar file.
+ Expected: EduContacts has a blank list of persons. A new `address.json` file will be created in the `data` folder after closing the app or executing a command. --------------------------------------------------------------------------------------------------------------------